/*
LICENSE

The MIT License (MIT)

Copyright (c) 2010 Michael Long

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef FAKE_FUNCTIONS
#define FAKE_FUNCTIONS

#include <stdarg.h>
#include <string.h> /* For memset and memcpy */

#define FFF_MAX_ARGS (20u)
#ifndef FFF_ARG_HISTORY_LEN
#define FFF_ARG_HISTORY_LEN (50u)
#endif
#ifndef FFF_CALL_HISTORY_LEN
#define FFF_CALL_HISTORY_LEN (50u)
#endif
#ifndef FFF_GCC_FUNCTION_ATTRIBUTES
#define FFF_GCC_FUNCTION_ATTRIBUTES
#endif
#ifndef CUSTOM_FFF_FUNCTION_TEMPLATE
#define CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN, FUNCNAME, ...) RETURN (*FUNCNAME)(__VA_ARGS__)
#endif /* CUSTOM_FFF_FUNCTION_TEMPLATE */
/* -- INTERNAL HELPER MACROS -- */
#define SET_RETURN_SEQ(FUNCNAME, ARRAY_POINTER, ARRAY_LEN)                                         \
	FUNCNAME##_fake.return_val_seq = ARRAY_POINTER;                                            \
	FUNCNAME##_fake.return_val_seq_len = ARRAY_LEN;
#define SET_CUSTOM_FAKE_SEQ(FUNCNAME, ARRAY_POINTER, ARRAY_LEN)                                    \
	FUNCNAME##_fake.custom_fake_seq = ARRAY_POINTER;                                           \
	FUNCNAME##_fake.custom_fake_seq_len = ARRAY_LEN;

/* Defining a function to reset a fake function */
#define RESET_FAKE(FUNCNAME)                                                                       \
	{                                                                                          \
		FUNCNAME##_reset();                                                                \
	}

#define DECLARE_ARG(type, n, FUNCNAME)                                                             \
	type arg##n##_val;                                                                         \
	type arg##n##_history[FFF_ARG_HISTORY_LEN];

#define DECLARE_ALL_FUNC_COMMON                                                                    \
	unsigned int call_count;                                                                   \
	unsigned int arg_history_len;                                                              \
	unsigned int arg_histories_dropped;

#define DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE)                                                  \
	RETURN_TYPE return_val_history[FFF_ARG_HISTORY_LEN];

#define SAVE_ARG(FUNCNAME, n)                                                                      \
	memcpy((void *)&FUNCNAME##_fake.arg##n##_val, (void *)&arg##n, sizeof(arg##n));

#define ROOM_FOR_MORE_HISTORY(FUNCNAME) FUNCNAME##_fake.call_count < FFF_ARG_HISTORY_LEN

#define SAVE_RET_HISTORY(FUNCNAME, RETVAL)                                                         \
	if ((FUNCNAME##_fake.call_count - 1) < FFF_ARG_HISTORY_LEN)                                \
		memcpy((void *)&FUNCNAME##_fake                                                    \
			       .return_val_history[FUNCNAME##_fake.call_count - 1],                \
		       (const void *)&RETVAL, sizeof(RETVAL));

#define SAVE_ARG_HISTORY(FUNCNAME, ARGN)                                                           \
	memcpy((void *)&FUNCNAME##_fake.arg##ARGN##_history[FUNCNAME##_fake.call_count],           \
	       (void *)&arg##ARGN, sizeof(arg##ARGN));

#define HISTORY_DROPPED(FUNCNAME) FUNCNAME##_fake.arg_histories_dropped++

#define DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE)                                              \
	RETURN_TYPE return_val;                                                                    \
	int return_val_seq_len;                                                                    \
	int return_val_seq_idx;                                                                    \
	RETURN_TYPE *return_val_seq;

#define DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                          \
	int custom_fake_seq_len;                                                                   \
	int custom_fake_seq_idx;

#define INCREMENT_CALL_COUNT(FUNCNAME) FUNCNAME##_fake.call_count++

#define RETURN_FAKE_RESULT(FUNCNAME)                                                               \
	if (FUNCNAME##_fake.return_val_seq_len) { /* then its a sequence */                        \
		if (FUNCNAME##_fake.return_val_seq_idx < FUNCNAME##_fake.return_val_seq_len) {     \
			SAVE_RET_HISTORY(                                                          \
				FUNCNAME,                                                          \
				FUNCNAME##_fake                                                    \
					.return_val_seq[FUNCNAME##_fake.return_val_seq_idx])       \
			return FUNCNAME##_fake                                                     \
				.return_val_seq[FUNCNAME##_fake.return_val_seq_idx++];             \
		}                                                                                  \
		SAVE_RET_HISTORY(                                                                  \
			FUNCNAME,                                                                  \
			FUNCNAME##_fake.return_val_seq[FUNCNAME##_fake.return_val_seq_len - 1])    \
		return FUNCNAME##_fake.return_val_seq[FUNCNAME##_fake.return_val_seq_len -         \
						      1]; /* return last element */                \
	}                                                                                          \
	SAVE_RET_HISTORY(FUNCNAME, FUNCNAME##_fake.return_val)                                     \
	return FUNCNAME##_fake.return_val;

#ifdef __cplusplus
#define FFF_EXTERN_C	 extern "C" {
#define FFF_END_EXTERN_C }
#else /* ansi c */
#define FFF_EXTERN_C
#define FFF_END_EXTERN_C
#endif /* cpp/ansi c */

#define DEFINE_RESET_FUNCTION(FUNCNAME)                                                            \
	void FUNCNAME##_reset(void)                                                                \
	{                                                                                          \
		memset((void *)&FUNCNAME##_fake, 0,                                                \
		       sizeof(FUNCNAME##_fake) - sizeof(FUNCNAME##_fake.custom_fake) -             \
			       sizeof(FUNCNAME##_fake.custom_fake_seq));                           \
		FUNCNAME##_fake.custom_fake = NULL;                                                \
		FUNCNAME##_fake.custom_fake_seq = NULL;                                            \
		FUNCNAME##_fake.arg_history_len = FFF_ARG_HISTORY_LEN;                             \
	}
/* -- END INTERNAL HELPER MACROS -- */

typedef void (*fff_function_t)(void);
typedef struct {
	fff_function_t call_history[FFF_CALL_HISTORY_LEN];
	unsigned int call_history_idx;
} fff_globals_t;

FFF_EXTERN_C
extern fff_globals_t fff;
FFF_END_EXTERN_C

#define DEFINE_FFF_GLOBALS                                                                         \
	FFF_EXTERN_C                                                                               \
	fff_globals_t fff;                                                                         \
	FFF_END_EXTERN_C

#define FFF_RESET_HISTORY()                                                                        \
	fff.call_history_idx = 0;                                                                  \
	memset(fff.call_history, 0, sizeof(fff.call_history));

#define REGISTER_CALL(function)                                                                    \
	if (fff.call_history_idx < FFF_CALL_HISTORY_LEN)                                           \
		fff.call_history[fff.call_history_idx++] = (fff_function_t)function;

#define DECLARE_FAKE_VOID_FUNC0(FUNCNAME)                                                          \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, void);                             \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, void);                        \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(void);

#define DEFINE_FAKE_VOID_FUNC0(FUNCNAME)                                                           \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(void)                                            \
	{                                                                                          \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](); \
			} else {                                                                   \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len -     \
							 1]();                                     \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake != NULL) {                                         \
			FUNCNAME##_fake.custom_fake();                                             \
		}                                                                                  \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VOID_FUNC0(FUNCNAME)                                                                  \
	DECLARE_FAKE_VOID_FUNC0(FUNCNAME)                                                          \
	DEFINE_FAKE_VOID_FUNC0(FUNCNAME)

#define DECLARE_FAKE_VOID_FUNC1(FUNCNAME, ARG0_TYPE)                                               \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE);                        \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE);                   \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0);

#define DEFINE_FAKE_VOID_FUNC1(FUNCNAME, ARG0_TYPE)                                                \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0)                                  \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](   \
						arg0);                                             \
			} else {                                                                   \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0);                                             \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake != NULL) {                                         \
			FUNCNAME##_fake.custom_fake(arg0);                                         \
		}                                                                                  \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VOID_FUNC1(FUNCNAME, ARG0_TYPE)                                                       \
	DECLARE_FAKE_VOID_FUNC1(FUNCNAME, ARG0_TYPE)                                               \
	DEFINE_FAKE_VOID_FUNC1(FUNCNAME, ARG0_TYPE)

#define DECLARE_FAKE_VOID_FUNC2(FUNCNAME, ARG0_TYPE, ARG1_TYPE)                                    \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE);             \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE);        \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1);

#define DEFINE_FAKE_VOID_FUNC2(FUNCNAME, ARG0_TYPE, ARG1_TYPE)                                     \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1)                  \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](   \
						arg0, arg1);                                       \
			} else {                                                                   \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1);                                       \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake != NULL) {                                         \
			FUNCNAME##_fake.custom_fake(arg0, arg1);                                   \
		}                                                                                  \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VOID_FUNC2(FUNCNAME, ARG0_TYPE, ARG1_TYPE)                                            \
	DECLARE_FAKE_VOID_FUNC2(FUNCNAME, ARG0_TYPE, ARG1_TYPE)                                    \
	DEFINE_FAKE_VOID_FUNC2(FUNCNAME, ARG0_TYPE, ARG1_TYPE)

#define DECLARE_FAKE_VOID_FUNC3(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE)                         \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE);  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,         \
					     ARG2_TYPE);                                           \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2);

#define DEFINE_FAKE_VOID_FUNC3(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE)                          \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2)  \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](   \
						arg0, arg1, arg2);                                 \
			} else {                                                                   \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2);                                 \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake != NULL) {                                         \
			FUNCNAME##_fake.custom_fake(arg0, arg1, arg2);                             \
		}                                                                                  \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VOID_FUNC3(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE)                                 \
	DECLARE_FAKE_VOID_FUNC3(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE)                         \
	DEFINE_FAKE_VOID_FUNC3(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE)

#define DECLARE_FAKE_VOID_FUNC4(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE)              \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					     ARG3_TYPE);                                           \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,         \
					     ARG2_TYPE, ARG3_TYPE);                                \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2,  \
						  ARG3_TYPE arg3);

#define DEFINE_FAKE_VOID_FUNC4(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE)               \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2,  \
						  ARG3_TYPE arg3)                                  \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](   \
						arg0, arg1, arg2, arg3);                           \
			} else {                                                                   \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3);                           \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake != NULL) {                                         \
			FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3);                       \
		}                                                                                  \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VOID_FUNC4(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE)                      \
	DECLARE_FAKE_VOID_FUNC4(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE)              \
	DEFINE_FAKE_VOID_FUNC4(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE)

#define DECLARE_FAKE_VOID_FUNC5(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE)   \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					     ARG3_TYPE, ARG4_TYPE);                                \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,         \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE);                     \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2,  \
						  ARG3_TYPE arg3, ARG4_TYPE arg4);

#define DEFINE_FAKE_VOID_FUNC5(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE)    \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2,  \
						  ARG3_TYPE arg3, ARG4_TYPE arg4)                  \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](   \
						arg0, arg1, arg2, arg3, arg4);                     \
			} else {                                                                   \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4);                     \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake != NULL) {                                         \
			FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4);                 \
		}                                                                                  \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VOID_FUNC5(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE)           \
	DECLARE_FAKE_VOID_FUNC5(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE)   \
	DEFINE_FAKE_VOID_FUNC5(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE)

#define DECLARE_FAKE_VOID_FUNC6(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,   \
				ARG5_TYPE)                                                         \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					     ARG3_TYPE, ARG4_TYPE, ARG5_TYPE);                     \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,         \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE);          \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2,  \
						  ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5);

#define DEFINE_FAKE_VOID_FUNC6(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,    \
			       ARG5_TYPE)                                                          \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2,  \
						  ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5)  \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](   \
						arg0, arg1, arg2, arg3, arg4, arg5);               \
			} else {                                                                   \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5);               \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake != NULL) {                                         \
			FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5);           \
		}                                                                                  \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VOID_FUNC6(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,           \
			ARG5_TYPE)                                                                 \
	DECLARE_FAKE_VOID_FUNC6(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,   \
				ARG5_TYPE)                                                         \
	DEFINE_FAKE_VOID_FUNC6(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,    \
			       ARG5_TYPE)

#define DECLARE_FAKE_VOID_FUNC7(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,   \
				ARG5_TYPE, ARG6_TYPE)                                              \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					     ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE);          \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,         \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE);                                           \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2,  \
						  ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5,  \
						  ARG6_TYPE arg6);

#define DEFINE_FAKE_VOID_FUNC7(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,    \
			       ARG5_TYPE, ARG6_TYPE)                                               \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2,  \
						  ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5,  \
						  ARG6_TYPE arg6)                                  \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](   \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6);         \
			} else {                                                                   \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6);         \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake != NULL) {                                         \
			FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6);     \
		}                                                                                  \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VOID_FUNC7(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,           \
			ARG5_TYPE, ARG6_TYPE)                                                      \
	DECLARE_FAKE_VOID_FUNC7(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,   \
				ARG5_TYPE, ARG6_TYPE)                                              \
	DEFINE_FAKE_VOID_FUNC7(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,    \
			       ARG5_TYPE, ARG6_TYPE)

#define DECLARE_FAKE_VOID_FUNC8(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,   \
				ARG5_TYPE, ARG6_TYPE, ARG7_TYPE)                                   \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					     ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE,           \
					     ARG7_TYPE);                                           \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,         \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE);                                \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2,  \
						  ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5,  \
						  ARG6_TYPE arg6, ARG7_TYPE arg7);

#define DEFINE_FAKE_VOID_FUNC8(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,    \
			       ARG5_TYPE, ARG6_TYPE, ARG7_TYPE)                                    \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2,  \
						  ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5,  \
						  ARG6_TYPE arg6, ARG7_TYPE arg7)                  \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](   \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7);   \
			} else {                                                                   \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7);   \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake != NULL) {                                         \
			FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6,      \
						    arg7);                                         \
		}                                                                                  \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VOID_FUNC8(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,           \
			ARG5_TYPE, ARG6_TYPE, ARG7_TYPE)                                           \
	DECLARE_FAKE_VOID_FUNC8(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,   \
				ARG5_TYPE, ARG6_TYPE, ARG7_TYPE)                                   \
	DEFINE_FAKE_VOID_FUNC8(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,    \
			       ARG5_TYPE, ARG6_TYPE, ARG7_TYPE)

#define DECLARE_FAKE_VOID_FUNC9(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,   \
				ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE)                        \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					     ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE,           \
					     ARG7_TYPE, ARG8_TYPE);                                \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,         \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE);                     \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2,  \
						  ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5,  \
						  ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8);

#define DEFINE_FAKE_VOID_FUNC9(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,    \
			       ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE)                         \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2,  \
						  ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5,  \
						  ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8)  \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](   \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8);                                             \
			} else {                                                                   \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8);                                             \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake != NULL) {                                         \
			FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6,      \
						    arg7, arg8);                                   \
		}                                                                                  \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VOID_FUNC9(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,           \
			ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE)                                \
	DECLARE_FAKE_VOID_FUNC9(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,   \
				ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE)                        \
	DEFINE_FAKE_VOID_FUNC9(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,    \
			       ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE)

#define DECLARE_FAKE_VOID_FUNC10(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,  \
				 ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE)            \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME)                                                \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					     ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE,           \
					     ARG7_TYPE, ARG8_TYPE, ARG9_TYPE);                     \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,         \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE);          \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                                 \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9);

#define DEFINE_FAKE_VOID_FUNC10(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,   \
				ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE)             \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                                 \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9)    \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		SAVE_ARG(FUNCNAME, 9);                                                             \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 9);                                             \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](   \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9);                                       \
			} else {                                                                   \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9);                                       \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake != NULL) {                                         \
			FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6,      \
						    arg7, arg8, arg9);                             \
		}                                                                                  \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VOID_FUNC10(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,          \
			 ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE)                    \
	DECLARE_FAKE_VOID_FUNC10(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,  \
				 ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE)            \
	DEFINE_FAKE_VOID_FUNC10(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,   \
				ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE)

#define DECLARE_FAKE_VOID_FUNC11(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,  \
				 ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,            \
				 ARG10_TYPE)                                                       \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME)                                                \
		DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME)                                              \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					     ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE,           \
					     ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE);         \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,         \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE);                                          \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2,  \
						  ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5,  \
						  ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8,  \
						  ARG9_TYPE arg9, ARG10_TYPE arg10);

#define DEFINE_FAKE_VOID_FUNC11(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,   \
				ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2,  \
						  ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5,  \
						  ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8,  \
						  ARG9_TYPE arg9, ARG10_TYPE arg10)                \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		SAVE_ARG(FUNCNAME, 9);                                                             \
		SAVE_ARG(FUNCNAME, 10);                                                            \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 9);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 10);                                            \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](   \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10);                                \
			} else {                                                                   \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10);                                \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake != NULL) {                                         \
			FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6,      \
						    arg7, arg8, arg9, arg10);                      \
		}                                                                                  \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VOID_FUNC11(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,          \
			 ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE)        \
	DECLARE_FAKE_VOID_FUNC11(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,  \
				 ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,            \
				 ARG10_TYPE)                                                       \
	DEFINE_FAKE_VOID_FUNC11(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,   \
				ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE)

#define DECLARE_FAKE_VOID_FUNC12(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,  \
				 ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,            \
				 ARG10_TYPE, ARG11_TYPE)                                           \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME)                                                \
		DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME)                                              \
		DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME)                                              \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					     ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE,           \
					     ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE,          \
					     ARG11_TYPE);                                          \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,         \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE);                              \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                                 \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11);

#define DEFINE_FAKE_VOID_FUNC12(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,   \
				ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, \
				ARG11_TYPE)                                                        \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                                 \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11)                                                \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		SAVE_ARG(FUNCNAME, 9);                                                             \
		SAVE_ARG(FUNCNAME, 10);                                                            \
		SAVE_ARG(FUNCNAME, 11);                                                            \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 9);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 10);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 11);                                            \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](   \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11);                         \
			} else {                                                                   \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11);                         \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake != NULL) {                                         \
			FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6,      \
						    arg7, arg8, arg9, arg10, arg11);               \
		}                                                                                  \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VOID_FUNC12(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,          \
			 ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE,        \
			 ARG11_TYPE)                                                               \
	DECLARE_FAKE_VOID_FUNC12(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,  \
				 ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,            \
				 ARG10_TYPE, ARG11_TYPE)                                           \
	DEFINE_FAKE_VOID_FUNC12(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,   \
				ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, \
				ARG11_TYPE)

#define DECLARE_FAKE_VOID_FUNC13(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,  \
				 ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,            \
				 ARG10_TYPE, ARG11_TYPE, ARG12_TYPE)                               \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME)                                                \
		DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME)                                              \
		DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME)                                              \
		DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME)                                              \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					     ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE,           \
					     ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE,          \
					     ARG11_TYPE, ARG12_TYPE);                              \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,         \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE);                  \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                                 \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12);

#define DEFINE_FAKE_VOID_FUNC13(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,   \
				ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, \
				ARG11_TYPE, ARG12_TYPE)                                            \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                                 \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12)                              \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		SAVE_ARG(FUNCNAME, 9);                                                             \
		SAVE_ARG(FUNCNAME, 10);                                                            \
		SAVE_ARG(FUNCNAME, 11);                                                            \
		SAVE_ARG(FUNCNAME, 12);                                                            \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 9);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 10);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 11);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 12);                                            \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](   \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12);                  \
			} else {                                                                   \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12);                  \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake != NULL) {                                         \
			FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6,      \
						    arg7, arg8, arg9, arg10, arg11, arg12);        \
		}                                                                                  \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VOID_FUNC13(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,          \
			 ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE,        \
			 ARG11_TYPE, ARG12_TYPE)                                                   \
	DECLARE_FAKE_VOID_FUNC13(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,  \
				 ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,            \
				 ARG10_TYPE, ARG11_TYPE, ARG12_TYPE)                               \
	DEFINE_FAKE_VOID_FUNC13(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,   \
				ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, \
				ARG11_TYPE, ARG12_TYPE)

#define DECLARE_FAKE_VOID_FUNC14(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,  \
				 ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,            \
				 ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE)                   \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME)                                                \
		DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME)                                              \
		DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME)                                              \
		DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME)                                              \
		DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME)                                              \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					     ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE,           \
					     ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE,          \
					     ARG11_TYPE, ARG12_TYPE, ARG13_TYPE);                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,         \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE);      \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                                 \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13);

#define DEFINE_FAKE_VOID_FUNC14(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,   \
				ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, \
				ARG11_TYPE, ARG12_TYPE, ARG13_TYPE)                                \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                                 \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13)            \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		SAVE_ARG(FUNCNAME, 9);                                                             \
		SAVE_ARG(FUNCNAME, 10);                                                            \
		SAVE_ARG(FUNCNAME, 11);                                                            \
		SAVE_ARG(FUNCNAME, 12);                                                            \
		SAVE_ARG(FUNCNAME, 13);                                                            \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 9);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 10);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 11);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 12);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 13);                                            \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](   \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12, arg13);           \
			} else {                                                                   \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12, arg13);           \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake != NULL) {                                         \
			FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6,      \
						    arg7, arg8, arg9, arg10, arg11, arg12, arg13); \
		}                                                                                  \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VOID_FUNC14(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,          \
			 ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE,        \
			 ARG11_TYPE, ARG12_TYPE, ARG13_TYPE)                                       \
	DECLARE_FAKE_VOID_FUNC14(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,  \
				 ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,            \
				 ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE)                   \
	DEFINE_FAKE_VOID_FUNC14(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,   \
				ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, \
				ARG11_TYPE, ARG12_TYPE, ARG13_TYPE)

#define DECLARE_FAKE_VOID_FUNC15(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,  \
				 ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,            \
				 ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE)       \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME)                                                \
		DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME)                                              \
		DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME)                                              \
		DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME)                                              \
		DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME)                                              \
		DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME)                                              \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					     ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE,           \
					     ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE,          \
					     ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE);      \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,         \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,       \
					     ARG14_TYPE);                                          \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                                 \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14);

#define DEFINE_FAKE_VOID_FUNC15(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,   \
				ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, \
				ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE)                    \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                                 \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14)                                                                  \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		SAVE_ARG(FUNCNAME, 9);                                                             \
		SAVE_ARG(FUNCNAME, 10);                                                            \
		SAVE_ARG(FUNCNAME, 11);                                                            \
		SAVE_ARG(FUNCNAME, 12);                                                            \
		SAVE_ARG(FUNCNAME, 13);                                                            \
		SAVE_ARG(FUNCNAME, 14);                                                            \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 9);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 10);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 11);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 12);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 13);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 14);                                            \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](   \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12, arg13, arg14);    \
			} else {                                                                   \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12, arg13, arg14);    \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake != NULL) {                                         \
			FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6,      \
						    arg7, arg8, arg9, arg10, arg11, arg12, arg13,  \
						    arg14);                                        \
		}                                                                                  \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VOID_FUNC15(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,          \
			 ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE,        \
			 ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE)                           \
	DECLARE_FAKE_VOID_FUNC15(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,  \
				 ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,            \
				 ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE)       \
	DEFINE_FAKE_VOID_FUNC15(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,   \
				ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, \
				ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE)

#define DECLARE_FAKE_VOID_FUNC16(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,  \
				 ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,            \
				 ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE,       \
				 ARG15_TYPE)                                                       \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME)                                                \
		DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME)                                              \
		DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME)                                              \
		DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME)                                              \
		DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME)                                              \
		DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME)                                              \
		DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME)                                              \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					     ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE,           \
					     ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE,          \
					     ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE,       \
					     ARG15_TYPE);                                          \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,         \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,       \
					     ARG14_TYPE, ARG15_TYPE);                              \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                                 \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14, ARG15_TYPE arg15);

#define DEFINE_FAKE_VOID_FUNC16(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,   \
				ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, \
				ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE)        \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                                 \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14, ARG15_TYPE arg15)                                                \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		SAVE_ARG(FUNCNAME, 9);                                                             \
		SAVE_ARG(FUNCNAME, 10);                                                            \
		SAVE_ARG(FUNCNAME, 11);                                                            \
		SAVE_ARG(FUNCNAME, 12);                                                            \
		SAVE_ARG(FUNCNAME, 13);                                                            \
		SAVE_ARG(FUNCNAME, 14);                                                            \
		SAVE_ARG(FUNCNAME, 15);                                                            \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 9);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 10);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 11);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 12);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 13);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 14);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 15);                                            \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](   \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12, arg13, arg14,     \
						arg15);                                            \
			} else {                                                                   \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12, arg13, arg14,     \
						arg15);                                            \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake != NULL) {                                         \
			FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6,      \
						    arg7, arg8, arg9, arg10, arg11, arg12, arg13,  \
						    arg14, arg15);                                 \
		}                                                                                  \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VOID_FUNC16(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,          \
			 ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE,        \
			 ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE)               \
	DECLARE_FAKE_VOID_FUNC16(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,  \
				 ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,            \
				 ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE,       \
				 ARG15_TYPE)                                                       \
	DEFINE_FAKE_VOID_FUNC16(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,   \
				ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, \
				ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE)

#define DECLARE_FAKE_VOID_FUNC17(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,  \
				 ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,            \
				 ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE,       \
				 ARG15_TYPE, ARG16_TYPE)                                           \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME)                                                \
		DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME)                                              \
		DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME)                                              \
		DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME)                                              \
		DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME)                                              \
		DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME)                                              \
		DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME)                                              \
		DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME)                                              \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					     ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE,           \
					     ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE,          \
					     ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE,       \
					     ARG15_TYPE, ARG16_TYPE);                              \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,         \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,       \
					     ARG14_TYPE, ARG15_TYPE, ARG16_TYPE);                  \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                                 \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16);

#define DEFINE_FAKE_VOID_FUNC17(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,   \
				ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, \
				ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE,        \
				ARG16_TYPE)                                                        \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                                 \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16)                              \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		SAVE_ARG(FUNCNAME, 9);                                                             \
		SAVE_ARG(FUNCNAME, 10);                                                            \
		SAVE_ARG(FUNCNAME, 11);                                                            \
		SAVE_ARG(FUNCNAME, 12);                                                            \
		SAVE_ARG(FUNCNAME, 13);                                                            \
		SAVE_ARG(FUNCNAME, 14);                                                            \
		SAVE_ARG(FUNCNAME, 15);                                                            \
		SAVE_ARG(FUNCNAME, 16);                                                            \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 9);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 10);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 11);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 12);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 13);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 14);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 15);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 16);                                            \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](   \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12, arg13, arg14,     \
						arg15, arg16);                                     \
			} else {                                                                   \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12, arg13, arg14,     \
						arg15, arg16);                                     \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake != NULL) {                                         \
			FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6,      \
						    arg7, arg8, arg9, arg10, arg11, arg12, arg13,  \
						    arg14, arg15, arg16);                          \
		}                                                                                  \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VOID_FUNC17(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,          \
			 ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE,        \
			 ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE)   \
	DECLARE_FAKE_VOID_FUNC17(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,  \
				 ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,            \
				 ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE,       \
				 ARG15_TYPE, ARG16_TYPE)                                           \
	DEFINE_FAKE_VOID_FUNC17(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,   \
				ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, \
				ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE,        \
				ARG16_TYPE)

#define DECLARE_FAKE_VOID_FUNC18(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,  \
				 ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,            \
				 ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE,       \
				 ARG15_TYPE, ARG16_TYPE, ARG17_TYPE)                               \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME)                                                \
		DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME)                                              \
		DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME)                                              \
		DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME)                                              \
		DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME)                                              \
		DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME)                                              \
		DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME)                                              \
		DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME)                                              \
		DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME)                                              \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					     ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE,           \
					     ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE,          \
					     ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE,       \
					     ARG15_TYPE, ARG16_TYPE, ARG17_TYPE);                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,         \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,       \
					     ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE);      \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                                 \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17);

#define DEFINE_FAKE_VOID_FUNC18(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,   \
				ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, \
				ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE,        \
				ARG16_TYPE, ARG17_TYPE)                                            \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                                 \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17)            \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		SAVE_ARG(FUNCNAME, 9);                                                             \
		SAVE_ARG(FUNCNAME, 10);                                                            \
		SAVE_ARG(FUNCNAME, 11);                                                            \
		SAVE_ARG(FUNCNAME, 12);                                                            \
		SAVE_ARG(FUNCNAME, 13);                                                            \
		SAVE_ARG(FUNCNAME, 14);                                                            \
		SAVE_ARG(FUNCNAME, 15);                                                            \
		SAVE_ARG(FUNCNAME, 16);                                                            \
		SAVE_ARG(FUNCNAME, 17);                                                            \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 9);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 10);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 11);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 12);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 13);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 14);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 15);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 16);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 17);                                            \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](   \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12, arg13, arg14,     \
						arg15, arg16, arg17);                              \
			} else {                                                                   \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12, arg13, arg14,     \
						arg15, arg16, arg17);                              \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake != NULL) {                                         \
			FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6,      \
						    arg7, arg8, arg9, arg10, arg11, arg12, arg13,  \
						    arg14, arg15, arg16, arg17);                   \
		}                                                                                  \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VOID_FUNC18(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,          \
			 ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE,        \
			 ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE,   \
			 ARG17_TYPE)                                                               \
	DECLARE_FAKE_VOID_FUNC18(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,  \
				 ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,            \
				 ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE,       \
				 ARG15_TYPE, ARG16_TYPE, ARG17_TYPE)                               \
	DEFINE_FAKE_VOID_FUNC18(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,   \
				ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, \
				ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE,        \
				ARG16_TYPE, ARG17_TYPE)

#define DECLARE_FAKE_VOID_FUNC19(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,  \
				 ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,            \
				 ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE,       \
				 ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE)                   \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME)                                                \
		DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME)                                              \
		DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME)                                              \
		DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME)                                              \
		DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME)                                              \
		DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME)                                              \
		DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME)                                              \
		DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME)                                              \
		DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME)                                              \
		DECLARE_ARG(ARG18_TYPE, 18, FUNCNAME)                                              \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					     ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE,           \
					     ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE,          \
					     ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE,       \
					     ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE);      \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,         \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,       \
					     ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE,       \
					     ARG18_TYPE);                                          \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                                 \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17,            \
		ARG18_TYPE arg18);

#define DEFINE_FAKE_VOID_FUNC19(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,   \
				ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, \
				ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE,        \
				ARG16_TYPE, ARG17_TYPE, ARG18_TYPE)                                \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                                 \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17,            \
		ARG18_TYPE arg18)                                                                  \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		SAVE_ARG(FUNCNAME, 9);                                                             \
		SAVE_ARG(FUNCNAME, 10);                                                            \
		SAVE_ARG(FUNCNAME, 11);                                                            \
		SAVE_ARG(FUNCNAME, 12);                                                            \
		SAVE_ARG(FUNCNAME, 13);                                                            \
		SAVE_ARG(FUNCNAME, 14);                                                            \
		SAVE_ARG(FUNCNAME, 15);                                                            \
		SAVE_ARG(FUNCNAME, 16);                                                            \
		SAVE_ARG(FUNCNAME, 17);                                                            \
		SAVE_ARG(FUNCNAME, 18);                                                            \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 9);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 10);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 11);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 12);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 13);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 14);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 15);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 16);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 17);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 18);                                            \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](   \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12, arg13, arg14,     \
						arg15, arg16, arg17, arg18);                       \
			} else {                                                                   \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12, arg13, arg14,     \
						arg15, arg16, arg17, arg18);                       \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake != NULL) {                                         \
			FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6,      \
						    arg7, arg8, arg9, arg10, arg11, arg12, arg13,  \
						    arg14, arg15, arg16, arg17, arg18);            \
		}                                                                                  \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VOID_FUNC19(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,          \
			 ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE,        \
			 ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE,   \
			 ARG17_TYPE, ARG18_TYPE)                                                   \
	DECLARE_FAKE_VOID_FUNC19(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,  \
				 ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,            \
				 ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE,       \
				 ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE)                   \
	DEFINE_FAKE_VOID_FUNC19(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,   \
				ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, \
				ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE,        \
				ARG16_TYPE, ARG17_TYPE, ARG18_TYPE)

#define DECLARE_FAKE_VOID_FUNC20(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,  \
				 ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,            \
				 ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE,       \
				 ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE)       \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME)                                                \
		DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME)                                              \
		DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME)                                              \
		DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME)                                              \
		DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME)                                              \
		DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME)                                              \
		DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME)                                              \
		DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME)                                              \
		DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME)                                              \
		DECLARE_ARG(ARG18_TYPE, 18, FUNCNAME)                                              \
		DECLARE_ARG(ARG19_TYPE, 19, FUNCNAME)                                              \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					     ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE,           \
					     ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE,          \
					     ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE,       \
					     ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE,       \
					     ARG19_TYPE);                                          \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,         \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,       \
					     ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE,       \
					     ARG18_TYPE, ARG19_TYPE);                              \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                                 \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17,            \
		ARG18_TYPE arg18, ARG19_TYPE arg19);

#define DEFINE_FAKE_VOID_FUNC20(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,   \
				ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, \
				ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE,        \
				ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE)                    \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                                 \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17,            \
		ARG18_TYPE arg18, ARG19_TYPE arg19)                                                \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		SAVE_ARG(FUNCNAME, 9);                                                             \
		SAVE_ARG(FUNCNAME, 10);                                                            \
		SAVE_ARG(FUNCNAME, 11);                                                            \
		SAVE_ARG(FUNCNAME, 12);                                                            \
		SAVE_ARG(FUNCNAME, 13);                                                            \
		SAVE_ARG(FUNCNAME, 14);                                                            \
		SAVE_ARG(FUNCNAME, 15);                                                            \
		SAVE_ARG(FUNCNAME, 16);                                                            \
		SAVE_ARG(FUNCNAME, 17);                                                            \
		SAVE_ARG(FUNCNAME, 18);                                                            \
		SAVE_ARG(FUNCNAME, 19);                                                            \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 9);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 10);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 11);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 12);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 13);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 14);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 15);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 16);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 17);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 18);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 19);                                            \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](   \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12, arg13, arg14,     \
						arg15, arg16, arg17, arg18, arg19);                \
			} else {                                                                   \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12, arg13, arg14,     \
						arg15, arg16, arg17, arg18, arg19);                \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake != NULL) {                                         \
			FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6,      \
						    arg7, arg8, arg9, arg10, arg11, arg12, arg13,  \
						    arg14, arg15, arg16, arg17, arg18, arg19);     \
		}                                                                                  \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VOID_FUNC20(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,          \
			 ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE,        \
			 ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE,   \
			 ARG17_TYPE, ARG18_TYPE, ARG19_TYPE)                                       \
	DECLARE_FAKE_VOID_FUNC20(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,  \
				 ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,            \
				 ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE,       \
				 ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE)       \
	DEFINE_FAKE_VOID_FUNC20(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,   \
				ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, \
				ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE,        \
				ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE)

#define DECLARE_FAKE_VALUE_FUNC0(RETURN_TYPE, FUNCNAME)                                            \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE)                                      \
		DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE)                                          \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, void);                      \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, void);                 \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(void);

#define DEFINE_FAKE_VALUE_FUNC0(RETURN_TYPE, FUNCNAME)                                             \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(void)                                     \
	{                                                                                          \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_idx++]();         \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				return ret;                                                        \
			} else {                                                                   \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_len - 1]();       \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				return ret;                                                        \
				return FUNCNAME##_fake                                             \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len -     \
							 1]();                                     \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake != NULL) {                                         \
			RETURN_TYPE ret = FUNCNAME##_fake.custom_fake();                           \
			SAVE_RET_HISTORY(FUNCNAME, ret);                                           \
			return ret;                                                                \
			return FUNCNAME##_fake.custom_fake();                                      \
		}                                                                                  \
		RETURN_FAKE_RESULT(FUNCNAME)                                                       \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VALUE_FUNC0(RETURN_TYPE, FUNCNAME)                                                    \
	DECLARE_FAKE_VALUE_FUNC0(RETURN_TYPE, FUNCNAME)                                            \
	DEFINE_FAKE_VALUE_FUNC0(RETURN_TYPE, FUNCNAME)

#define DECLARE_FAKE_VALUE_FUNC1(RETURN_TYPE, FUNCNAME, ARG0_TYPE)                                 \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE)                                      \
		DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE)                                          \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE);                 \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE);            \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0);

#define DEFINE_FAKE_VALUE_FUNC1(RETURN_TYPE, FUNCNAME, ARG0_TYPE)                                  \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0)                           \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_idx++](arg0);     \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				return ret;                                                        \
			} else {                                                                   \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_len - 1](arg0);   \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				return ret;                                                        \
				return FUNCNAME##_fake                                             \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0);                                             \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake != NULL) {                                         \
			RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0);                       \
			SAVE_RET_HISTORY(FUNCNAME, ret);                                           \
			return ret;                                                                \
			return FUNCNAME##_fake.custom_fake(arg0);                                  \
		}                                                                                  \
		RETURN_FAKE_RESULT(FUNCNAME)                                                       \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VALUE_FUNC1(RETURN_TYPE, FUNCNAME, ARG0_TYPE)                                         \
	DECLARE_FAKE_VALUE_FUNC1(RETURN_TYPE, FUNCNAME, ARG0_TYPE)                                 \
	DEFINE_FAKE_VALUE_FUNC1(RETURN_TYPE, FUNCNAME, ARG0_TYPE)

#define DECLARE_FAKE_VALUE_FUNC2(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE)                      \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE)                                      \
		DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE)                                          \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE);      \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE); \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1);

#define DEFINE_FAKE_VALUE_FUNC2(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE)                       \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1)           \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq                  \
							  [FUNCNAME##_fake.custom_fake_seq_idx++]( \
								  arg0, arg1);                     \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				return ret;                                                        \
			} else {                                                                   \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_len - 1](arg0,    \
											  arg1);   \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				return ret;                                                        \
				return FUNCNAME##_fake                                             \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1);                                       \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake != NULL) {                                         \
			RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1);                 \
			SAVE_RET_HISTORY(FUNCNAME, ret);                                           \
			return ret;                                                                \
			return FUNCNAME##_fake.custom_fake(arg0, arg1);                            \
		}                                                                                  \
		RETURN_FAKE_RESULT(FUNCNAME)                                                       \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VALUE_FUNC2(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE)                              \
	DECLARE_FAKE_VALUE_FUNC2(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE)                      \
	DEFINE_FAKE_VALUE_FUNC2(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE)

#define DECLARE_FAKE_VALUE_FUNC3(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE)           \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE)                                      \
		DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE)                                          \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE,       \
					     ARG2_TYPE);                                           \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,  \
					     ARG2_TYPE);                                           \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1,           \
							 ARG2_TYPE arg2);

#define DEFINE_FAKE_VALUE_FUNC3(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE)            \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1,           \
							 ARG2_TYPE arg2)                           \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq                  \
							  [FUNCNAME##_fake.custom_fake_seq_idx++]( \
								  arg0, arg1, arg2);               \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				return ret;                                                        \
			} else {                                                                   \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_len - 1](         \
							arg0, arg1, arg2);                         \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				return ret;                                                        \
				return FUNCNAME##_fake                                             \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2);                                 \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake != NULL) {                                         \
			RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2);           \
			SAVE_RET_HISTORY(FUNCNAME, ret);                                           \
			return ret;                                                                \
			return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2);                      \
		}                                                                                  \
		RETURN_FAKE_RESULT(FUNCNAME)                                                       \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VALUE_FUNC3(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE)                   \
	DECLARE_FAKE_VALUE_FUNC3(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE)           \
	DEFINE_FAKE_VALUE_FUNC3(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE)

#define DECLARE_FAKE_VALUE_FUNC4(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE)                                                        \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE)                                      \
		DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE)                                          \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE,       \
					     ARG2_TYPE, ARG3_TYPE);                                \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,  \
					     ARG2_TYPE, ARG3_TYPE);                                \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1,           \
							 ARG2_TYPE arg2, ARG3_TYPE arg3);

#define DEFINE_FAKE_VALUE_FUNC4(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1,           \
							 ARG2_TYPE arg2, ARG3_TYPE arg3)           \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq                  \
							  [FUNCNAME##_fake.custom_fake_seq_idx++]( \
								  arg0, arg1, arg2, arg3);         \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				return ret;                                                        \
			} else {                                                                   \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_len - 1](         \
							arg0, arg1, arg2, arg3);                   \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				return ret;                                                        \
				return FUNCNAME##_fake                                             \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3);                           \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake != NULL) {                                         \
			RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3);     \
			SAVE_RET_HISTORY(FUNCNAME, ret);                                           \
			return ret;                                                                \
			return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3);                \
		}                                                                                  \
		RETURN_FAKE_RESULT(FUNCNAME)                                                       \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VALUE_FUNC4(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE)        \
	DECLARE_FAKE_VALUE_FUNC4(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE)                                                        \
	DEFINE_FAKE_VALUE_FUNC4(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE)

#define DECLARE_FAKE_VALUE_FUNC5(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE, ARG4_TYPE)                                             \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE)                                      \
		DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE)                                          \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE,       \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE);                     \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,  \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE);                     \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4);

#define DEFINE_FAKE_VALUE_FUNC5(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, \
				ARG4_TYPE)                                                         \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4)    \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq                  \
							  [FUNCNAME##_fake.custom_fake_seq_idx++]( \
								  arg0, arg1, arg2, arg3, arg4);   \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				return ret;                                                        \
			} else {                                                                   \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_len - 1](         \
							arg0, arg1, arg2, arg3, arg4);             \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				return ret;                                                        \
				return FUNCNAME##_fake                                             \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4);                     \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake != NULL) {                                         \
			RETURN_TYPE ret =                                                          \
				FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4);         \
			SAVE_RET_HISTORY(FUNCNAME, ret);                                           \
			return ret;                                                                \
			return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4);          \
		}                                                                                  \
		RETURN_FAKE_RESULT(FUNCNAME)                                                       \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VALUE_FUNC5(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,        \
			 ARG4_TYPE)                                                                \
	DECLARE_FAKE_VALUE_FUNC5(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE, ARG4_TYPE)                                             \
	DEFINE_FAKE_VALUE_FUNC5(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, \
				ARG4_TYPE)

#define DECLARE_FAKE_VALUE_FUNC6(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE)                                  \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE)                                      \
		DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE)                                          \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE,       \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE);          \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,  \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE);          \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1,           \
							 ARG2_TYPE arg2, ARG3_TYPE arg3,           \
							 ARG4_TYPE arg4, ARG5_TYPE arg5);

#define DEFINE_FAKE_VALUE_FUNC6(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, \
				ARG4_TYPE, ARG5_TYPE)                                              \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1,           \
							 ARG2_TYPE arg2, ARG3_TYPE arg3,           \
							 ARG4_TYPE arg4, ARG5_TYPE arg5)           \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_idx++](           \
							arg0, arg1, arg2, arg3, arg4, arg5);       \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				return ret;                                                        \
			} else {                                                                   \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_len - 1](         \
							arg0, arg1, arg2, arg3, arg4, arg5);       \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				return ret;                                                        \
				return FUNCNAME##_fake                                             \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5);               \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake != NULL) {                                         \
			RETURN_TYPE ret =                                                          \
				FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5);   \
			SAVE_RET_HISTORY(FUNCNAME, ret);                                           \
			return ret;                                                                \
			return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5);    \
		}                                                                                  \
		RETURN_FAKE_RESULT(FUNCNAME)                                                       \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VALUE_FUNC6(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,        \
			 ARG4_TYPE, ARG5_TYPE)                                                     \
	DECLARE_FAKE_VALUE_FUNC6(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE)                                  \
	DEFINE_FAKE_VALUE_FUNC6(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, \
				ARG4_TYPE, ARG5_TYPE)

#define DECLARE_FAKE_VALUE_FUNC7(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE)                       \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE)                                      \
		DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE)                                          \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE,       \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE);                                           \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,  \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE);                                           \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6);

#define DEFINE_FAKE_VALUE_FUNC7(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, \
				ARG4_TYPE, ARG5_TYPE, ARG6_TYPE)                                   \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6)                                                    \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_idx++](           \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6); \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				return ret;                                                        \
			} else {                                                                   \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_len - 1](         \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6); \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				return ret;                                                        \
				return FUNCNAME##_fake                                             \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6);         \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake != NULL) {                                         \
			RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3,      \
								      arg4, arg5, arg6);           \
			SAVE_RET_HISTORY(FUNCNAME, ret);                                           \
			return ret;                                                                \
			return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5,     \
							   arg6);                                  \
		}                                                                                  \
		RETURN_FAKE_RESULT(FUNCNAME)                                                       \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VALUE_FUNC7(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,        \
			 ARG4_TYPE, ARG5_TYPE, ARG6_TYPE)                                          \
	DECLARE_FAKE_VALUE_FUNC7(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE)                       \
	DEFINE_FAKE_VALUE_FUNC7(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, \
				ARG4_TYPE, ARG5_TYPE, ARG6_TYPE)

#define DECLARE_FAKE_VALUE_FUNC8(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE)            \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE)                                      \
		DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE)                                          \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE,       \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE);                                \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,  \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE);                                \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7);

#define DEFINE_FAKE_VALUE_FUNC8(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, \
				ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE)                        \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7)                                    \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq                  \
							  [FUNCNAME##_fake.custom_fake_seq_idx++]( \
								  arg0, arg1, arg2, arg3, arg4,    \
								  arg5, arg6, arg7);               \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				return ret;                                                        \
			} else {                                                                   \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_len - 1](         \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							arg7);                                     \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				return ret;                                                        \
				return FUNCNAME##_fake                                             \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7);   \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake != NULL) {                                         \
			RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3,      \
								      arg4, arg5, arg6, arg7);     \
			SAVE_RET_HISTORY(FUNCNAME, ret);                                           \
			return ret;                                                                \
			return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5,     \
							   arg6, arg7);                            \
		}                                                                                  \
		RETURN_FAKE_RESULT(FUNCNAME)                                                       \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VALUE_FUNC8(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,        \
			 ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE)                               \
	DECLARE_FAKE_VALUE_FUNC8(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE)            \
	DEFINE_FAKE_VALUE_FUNC8(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, \
				ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE)

#define DECLARE_FAKE_VALUE_FUNC9(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE)                                      \
		DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE)                                          \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE,       \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE);                     \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,  \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE);                     \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8);

#define DEFINE_FAKE_VALUE_FUNC9(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, \
				ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE)             \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8)                    \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq                  \
							  [FUNCNAME##_fake.custom_fake_seq_idx++]( \
								  arg0, arg1, arg2, arg3, arg4,    \
								  arg5, arg6, arg7, arg8);         \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				return ret;                                                        \
			} else {                                                                   \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_len - 1](         \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							arg7, arg8);                               \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				return ret;                                                        \
				return FUNCNAME##_fake                                             \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8);                                             \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake != NULL) {                                         \
			RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(                             \
				arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);             \
			SAVE_RET_HISTORY(FUNCNAME, ret);                                           \
			return ret;                                                                \
			return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5,     \
							   arg6, arg7, arg8);                      \
		}                                                                                  \
		RETURN_FAKE_RESULT(FUNCNAME)                                                       \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VALUE_FUNC9(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,        \
			 ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE)                    \
	DECLARE_FAKE_VALUE_FUNC9(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \
	DEFINE_FAKE_VALUE_FUNC9(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, \
				ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE)

#define DECLARE_FAKE_VALUE_FUNC10(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,          \
				  ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,           \
				  ARG8_TYPE, ARG9_TYPE)                                            \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME)                                                \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE)                                      \
		DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE)                                          \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE,       \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE);          \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,  \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE);          \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9);

#define DEFINE_FAKE_VALUE_FUNC10(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, \
				 ARG9_TYPE)                                                        \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9)    \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		SAVE_ARG(FUNCNAME, 9);                                                             \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 9);                                             \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq                  \
							  [FUNCNAME##_fake.custom_fake_seq_idx++]( \
								  arg0, arg1, arg2, arg3, arg4,    \
								  arg5, arg6, arg7, arg8, arg9);   \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				return ret;                                                        \
			} else {                                                                   \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_len - 1](         \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							arg7, arg8, arg9);                         \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				return ret;                                                        \
				return FUNCNAME##_fake                                             \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9);                                       \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake != NULL) {                                         \
			RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(                             \
				arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);       \
			SAVE_RET_HISTORY(FUNCNAME, ret);                                           \
			return ret;                                                                \
			return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5,     \
							   arg6, arg7, arg8, arg9);                \
		}                                                                                  \
		RETURN_FAKE_RESULT(FUNCNAME)                                                       \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VALUE_FUNC10(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,       \
			  ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE)        \
	DECLARE_FAKE_VALUE_FUNC10(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,          \
				  ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,           \
				  ARG8_TYPE, ARG9_TYPE)                                            \
	DEFINE_FAKE_VALUE_FUNC10(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, \
				 ARG9_TYPE)

#define DECLARE_FAKE_VALUE_FUNC11(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,          \
				  ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,           \
				  ARG8_TYPE, ARG9_TYPE, ARG10_TYPE)                                \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME)                                                \
		DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME)                                              \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE)                                      \
		DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE)                                          \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE,       \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE);                                          \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,  \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE);                                          \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10);

#define DEFINE_FAKE_VALUE_FUNC11(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, \
				 ARG9_TYPE, ARG10_TYPE)                                            \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10)                                                                  \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		SAVE_ARG(FUNCNAME, 9);                                                             \
		SAVE_ARG(FUNCNAME, 10);                                                            \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 9);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 10);                                            \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_idx++](           \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							arg7, arg8, arg9, arg10);                  \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				return ret;                                                        \
			} else {                                                                   \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_len - 1](         \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							arg7, arg8, arg9, arg10);                  \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				return ret;                                                        \
				return FUNCNAME##_fake                                             \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10);                                \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake != NULL) {                                         \
			RETURN_TYPE ret =                                                          \
				FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5,    \
							    arg6, arg7, arg8, arg9, arg10);        \
			SAVE_RET_HISTORY(FUNCNAME, ret);                                           \
			return ret;                                                                \
			return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5,     \
							   arg6, arg7, arg8, arg9, arg10);         \
		}                                                                                  \
		RETURN_FAKE_RESULT(FUNCNAME)                                                       \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VALUE_FUNC11(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,       \
			  ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,        \
			  ARG10_TYPE)                                                              \
	DECLARE_FAKE_VALUE_FUNC11(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,          \
				  ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,           \
				  ARG8_TYPE, ARG9_TYPE, ARG10_TYPE)                                \
	DEFINE_FAKE_VALUE_FUNC11(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, \
				 ARG9_TYPE, ARG10_TYPE)

#define DECLARE_FAKE_VALUE_FUNC12(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,          \
				  ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,           \
				  ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE)                    \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME)                                                \
		DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME)                                              \
		DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME)                                              \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE)                                      \
		DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE)                                          \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE,       \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE);                              \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,  \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE);                              \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11);

#define DEFINE_FAKE_VALUE_FUNC12(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, \
				 ARG9_TYPE, ARG10_TYPE, ARG11_TYPE)                                \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11)                                                \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		SAVE_ARG(FUNCNAME, 9);                                                             \
		SAVE_ARG(FUNCNAME, 10);                                                            \
		SAVE_ARG(FUNCNAME, 11);                                                            \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 9);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 10);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 11);                                            \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_idx++](           \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							arg7, arg8, arg9, arg10, arg11);           \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				return ret;                                                        \
			} else {                                                                   \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_len - 1](         \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							arg7, arg8, arg9, arg10, arg11);           \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				return ret;                                                        \
				return FUNCNAME##_fake                                             \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11);                         \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake != NULL) {                                         \
			RETURN_TYPE ret =                                                          \
				FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5,    \
							    arg6, arg7, arg8, arg9, arg10, arg11); \
			SAVE_RET_HISTORY(FUNCNAME, ret);                                           \
			return ret;                                                                \
			return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5,     \
							   arg6, arg7, arg8, arg9, arg10, arg11);  \
		}                                                                                  \
		RETURN_FAKE_RESULT(FUNCNAME)                                                       \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VALUE_FUNC12(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,       \
			  ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,        \
			  ARG10_TYPE, ARG11_TYPE)                                                  \
	DECLARE_FAKE_VALUE_FUNC12(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,          \
				  ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,           \
				  ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE)                    \
	DEFINE_FAKE_VALUE_FUNC12(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, \
				 ARG9_TYPE, ARG10_TYPE, ARG11_TYPE)

#define DECLARE_FAKE_VALUE_FUNC13(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,          \
				  ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,           \
				  ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE)        \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME)                                                \
		DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME)                                              \
		DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME)                                              \
		DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME)                                              \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE)                                      \
		DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE)                                          \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE,       \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE);                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,  \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE);                  \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12);

#define DEFINE_FAKE_VALUE_FUNC13(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, \
				 ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE)                    \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12)                              \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		SAVE_ARG(FUNCNAME, 9);                                                             \
		SAVE_ARG(FUNCNAME, 10);                                                            \
		SAVE_ARG(FUNCNAME, 11);                                                            \
		SAVE_ARG(FUNCNAME, 12);                                                            \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 9);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 10);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 11);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 12);                                            \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_idx++](           \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							arg7, arg8, arg9, arg10, arg11, arg12);    \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				return ret;                                                        \
			} else {                                                                   \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_len - 1](         \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							arg7, arg8, arg9, arg10, arg11, arg12);    \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				return ret;                                                        \
				return FUNCNAME##_fake                                             \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12);                  \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake != NULL) {                                         \
			RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(                             \
				arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, \
				arg11, arg12);                                                     \
			SAVE_RET_HISTORY(FUNCNAME, ret);                                           \
			return ret;                                                                \
			return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5,     \
							   arg6, arg7, arg8, arg9, arg10, arg11,   \
							   arg12);                                 \
		}                                                                                  \
		RETURN_FAKE_RESULT(FUNCNAME)                                                       \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VALUE_FUNC13(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,       \
			  ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,        \
			  ARG10_TYPE, ARG11_TYPE, ARG12_TYPE)                                      \
	DECLARE_FAKE_VALUE_FUNC13(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,          \
				  ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,           \
				  ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE)        \
	DEFINE_FAKE_VALUE_FUNC13(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, \
				 ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE)

#define DECLARE_FAKE_VALUE_FUNC14(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,          \
				  ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,           \
				  ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE,        \
				  ARG13_TYPE)                                                      \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME)                                                \
		DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME)                                              \
		DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME)                                              \
		DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME)                                              \
		DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME)                                              \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE)                                      \
		DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE)                                          \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE,       \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE);      \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,  \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE);      \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13);

#define DEFINE_FAKE_VALUE_FUNC14(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, \
				 ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE)        \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13)            \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		SAVE_ARG(FUNCNAME, 9);                                                             \
		SAVE_ARG(FUNCNAME, 10);                                                            \
		SAVE_ARG(FUNCNAME, 11);                                                            \
		SAVE_ARG(FUNCNAME, 12);                                                            \
		SAVE_ARG(FUNCNAME, 13);                                                            \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 9);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 10);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 11);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 12);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 13);                                            \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq                  \
							  [FUNCNAME##_fake.custom_fake_seq_idx++]( \
								  arg0, arg1, arg2, arg3, arg4,    \
								  arg5, arg6, arg7, arg8, arg9,    \
								  arg10, arg11, arg12, arg13);     \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				return ret;                                                        \
			} else {                                                                   \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_len - 1](         \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							arg7, arg8, arg9, arg10, arg11, arg12,     \
							arg13);                                    \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				return ret;                                                        \
				return FUNCNAME##_fake                                             \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12, arg13);           \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake != NULL) {                                         \
			RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(                             \
				arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, \
				arg11, arg12, arg13);                                              \
			SAVE_RET_HISTORY(FUNCNAME, ret);                                           \
			return ret;                                                                \
			return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5,     \
							   arg6, arg7, arg8, arg9, arg10, arg11,   \
							   arg12, arg13);                          \
		}                                                                                  \
		RETURN_FAKE_RESULT(FUNCNAME)                                                       \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VALUE_FUNC14(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,       \
			  ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,        \
			  ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE)                          \
	DECLARE_FAKE_VALUE_FUNC14(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,          \
				  ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,           \
				  ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE,        \
				  ARG13_TYPE)                                                      \
	DEFINE_FAKE_VALUE_FUNC14(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, \
				 ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE)

#define DECLARE_FAKE_VALUE_FUNC15(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,          \
				  ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,           \
				  ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE,        \
				  ARG13_TYPE, ARG14_TYPE)                                          \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME)                                                \
		DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME)                                              \
		DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME)                                              \
		DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME)                                              \
		DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME)                                              \
		DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME)                                              \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE)                                      \
		DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE)                                          \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE,       \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,       \
					     ARG14_TYPE);                                          \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,  \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,       \
					     ARG14_TYPE);                                          \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14);

#define DEFINE_FAKE_VALUE_FUNC15(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, \
				 ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,        \
				 ARG14_TYPE)                                                       \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14)                                                                  \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		SAVE_ARG(FUNCNAME, 9);                                                             \
		SAVE_ARG(FUNCNAME, 10);                                                            \
		SAVE_ARG(FUNCNAME, 11);                                                            \
		SAVE_ARG(FUNCNAME, 12);                                                            \
		SAVE_ARG(FUNCNAME, 13);                                                            \
		SAVE_ARG(FUNCNAME, 14);                                                            \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 9);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 10);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 11);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 12);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 13);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 14);                                            \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_idx++](           \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							arg7, arg8, arg9, arg10, arg11, arg12,     \
							arg13, arg14);                             \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				return ret;                                                        \
			} else {                                                                   \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_len - 1](         \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							arg7, arg8, arg9, arg10, arg11, arg12,     \
							arg13, arg14);                             \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				return ret;                                                        \
				return FUNCNAME##_fake                                             \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12, arg13, arg14);    \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake != NULL) {                                         \
			RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(                             \
				arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, \
				arg11, arg12, arg13, arg14);                                       \
			SAVE_RET_HISTORY(FUNCNAME, ret);                                           \
			return ret;                                                                \
			return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5,     \
							   arg6, arg7, arg8, arg9, arg10, arg11,   \
							   arg12, arg13, arg14);                   \
		}                                                                                  \
		RETURN_FAKE_RESULT(FUNCNAME)                                                       \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VALUE_FUNC15(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,       \
			  ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,        \
			  ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE)              \
	DECLARE_FAKE_VALUE_FUNC15(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,          \
				  ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,           \
				  ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE,        \
				  ARG13_TYPE, ARG14_TYPE)                                          \
	DEFINE_FAKE_VALUE_FUNC15(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, \
				 ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,        \
				 ARG14_TYPE)

#define DECLARE_FAKE_VALUE_FUNC16(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,          \
				  ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,           \
				  ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE,        \
				  ARG13_TYPE, ARG14_TYPE, ARG15_TYPE)                              \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME)                                                \
		DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME)                                              \
		DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME)                                              \
		DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME)                                              \
		DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME)                                              \
		DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME)                                              \
		DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME)                                              \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE)                                      \
		DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE)                                          \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE,       \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,       \
					     ARG14_TYPE, ARG15_TYPE);                              \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,  \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,       \
					     ARG14_TYPE, ARG15_TYPE);                              \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14, ARG15_TYPE arg15);

#define DEFINE_FAKE_VALUE_FUNC16(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, \
				 ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,        \
				 ARG14_TYPE, ARG15_TYPE)                                           \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14, ARG15_TYPE arg15)                                                \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		SAVE_ARG(FUNCNAME, 9);                                                             \
		SAVE_ARG(FUNCNAME, 10);                                                            \
		SAVE_ARG(FUNCNAME, 11);                                                            \
		SAVE_ARG(FUNCNAME, 12);                                                            \
		SAVE_ARG(FUNCNAME, 13);                                                            \
		SAVE_ARG(FUNCNAME, 14);                                                            \
		SAVE_ARG(FUNCNAME, 15);                                                            \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 9);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 10);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 11);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 12);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 13);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 14);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 15);                                            \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_idx++](           \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							arg7, arg8, arg9, arg10, arg11, arg12,     \
							arg13, arg14, arg15);                      \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				return ret;                                                        \
			} else {                                                                   \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_len - 1](         \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							arg7, arg8, arg9, arg10, arg11, arg12,     \
							arg13, arg14, arg15);                      \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				return ret;                                                        \
				return FUNCNAME##_fake                                             \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12, arg13, arg14,     \
						arg15);                                            \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake != NULL) {                                         \
			RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(                             \
				arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, \
				arg11, arg12, arg13, arg14, arg15);                                \
			SAVE_RET_HISTORY(FUNCNAME, ret);                                           \
			return ret;                                                                \
			return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5,     \
							   arg6, arg7, arg8, arg9, arg10, arg11,   \
							   arg12, arg13, arg14, arg15);            \
		}                                                                                  \
		RETURN_FAKE_RESULT(FUNCNAME)                                                       \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VALUE_FUNC16(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,       \
			  ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,        \
			  ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE)  \
	DECLARE_FAKE_VALUE_FUNC16(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,          \
				  ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,           \
				  ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE,        \
				  ARG13_TYPE, ARG14_TYPE, ARG15_TYPE)                              \
	DEFINE_FAKE_VALUE_FUNC16(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, \
				 ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,        \
				 ARG14_TYPE, ARG15_TYPE)

#define DECLARE_FAKE_VALUE_FUNC17(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,          \
				  ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,           \
				  ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE,        \
				  ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE)                  \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME)                                                \
		DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME)                                              \
		DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME)                                              \
		DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME)                                              \
		DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME)                                              \
		DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME)                                              \
		DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME)                                              \
		DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME)                                              \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE)                                      \
		DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE)                                          \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE,       \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,       \
					     ARG14_TYPE, ARG15_TYPE, ARG16_TYPE);                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,  \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,       \
					     ARG14_TYPE, ARG15_TYPE, ARG16_TYPE);                  \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16);

#define DEFINE_FAKE_VALUE_FUNC17(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, \
				 ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,        \
				 ARG14_TYPE, ARG15_TYPE, ARG16_TYPE)                               \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16)                              \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		SAVE_ARG(FUNCNAME, 9);                                                             \
		SAVE_ARG(FUNCNAME, 10);                                                            \
		SAVE_ARG(FUNCNAME, 11);                                                            \
		SAVE_ARG(FUNCNAME, 12);                                                            \
		SAVE_ARG(FUNCNAME, 13);                                                            \
		SAVE_ARG(FUNCNAME, 14);                                                            \
		SAVE_ARG(FUNCNAME, 15);                                                            \
		SAVE_ARG(FUNCNAME, 16);                                                            \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 9);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 10);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 11);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 12);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 13);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 14);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 15);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 16);                                            \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_idx++](           \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							arg7, arg8, arg9, arg10, arg11, arg12,     \
							arg13, arg14, arg15, arg16);               \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				return ret;                                                        \
			} else {                                                                   \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_len - 1](         \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							arg7, arg8, arg9, arg10, arg11, arg12,     \
							arg13, arg14, arg15, arg16);               \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				return ret;                                                        \
				return FUNCNAME##_fake                                             \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12, arg13, arg14,     \
						arg15, arg16);                                     \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake != NULL) {                                         \
			RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(                             \
				arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, \
				arg11, arg12, arg13, arg14, arg15, arg16);                         \
			SAVE_RET_HISTORY(FUNCNAME, ret);                                           \
			return ret;                                                                \
			return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5,     \
							   arg6, arg7, arg8, arg9, arg10, arg11,   \
							   arg12, arg13, arg14, arg15, arg16);     \
		}                                                                                  \
		RETURN_FAKE_RESULT(FUNCNAME)                                                       \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VALUE_FUNC17(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,       \
			  ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,        \
			  ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE,  \
			  ARG16_TYPE)                                                              \
	DECLARE_FAKE_VALUE_FUNC17(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,          \
				  ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,           \
				  ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE,        \
				  ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE)                  \
	DEFINE_FAKE_VALUE_FUNC17(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, \
				 ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,        \
				 ARG14_TYPE, ARG15_TYPE, ARG16_TYPE)

#define DECLARE_FAKE_VALUE_FUNC18(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,          \
				  ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,           \
				  ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE,        \
				  ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE)      \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME)                                                \
		DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME)                                              \
		DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME)                                              \
		DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME)                                              \
		DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME)                                              \
		DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME)                                              \
		DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME)                                              \
		DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME)                                              \
		DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME)                                              \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE)                                      \
		DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE)                                          \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE,       \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,       \
					     ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE);      \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,  \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,       \
					     ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE);      \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17);

#define DEFINE_FAKE_VALUE_FUNC18(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, \
				 ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,        \
				 ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE)                   \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17)            \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		SAVE_ARG(FUNCNAME, 9);                                                             \
		SAVE_ARG(FUNCNAME, 10);                                                            \
		SAVE_ARG(FUNCNAME, 11);                                                            \
		SAVE_ARG(FUNCNAME, 12);                                                            \
		SAVE_ARG(FUNCNAME, 13);                                                            \
		SAVE_ARG(FUNCNAME, 14);                                                            \
		SAVE_ARG(FUNCNAME, 15);                                                            \
		SAVE_ARG(FUNCNAME, 16);                                                            \
		SAVE_ARG(FUNCNAME, 17);                                                            \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 9);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 10);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 11);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 12);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 13);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 14);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 15);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 16);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 17);                                            \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_idx++](           \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							arg7, arg8, arg9, arg10, arg11, arg12,     \
							arg13, arg14, arg15, arg16, arg17);        \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				return ret;                                                        \
			} else {                                                                   \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_len - 1](         \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							arg7, arg8, arg9, arg10, arg11, arg12,     \
							arg13, arg14, arg15, arg16, arg17);        \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				return ret;                                                        \
				return FUNCNAME##_fake                                             \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12, arg13, arg14,     \
						arg15, arg16, arg17);                              \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake != NULL) {                                         \
			RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(                             \
				arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, \
				arg11, arg12, arg13, arg14, arg15, arg16, arg17);                  \
			SAVE_RET_HISTORY(FUNCNAME, ret);                                           \
			return ret;                                                                \
			return FUNCNAME##_fake.custom_fake(                                        \
				arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, \
				arg11, arg12, arg13, arg14, arg15, arg16, arg17);                  \
		}                                                                                  \
		RETURN_FAKE_RESULT(FUNCNAME)                                                       \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VALUE_FUNC18(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,       \
			  ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,        \
			  ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE,  \
			  ARG16_TYPE, ARG17_TYPE)                                                  \
	DECLARE_FAKE_VALUE_FUNC18(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,          \
				  ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,           \
				  ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE,        \
				  ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE)      \
	DEFINE_FAKE_VALUE_FUNC18(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, \
				 ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,        \
				 ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE)

#define DECLARE_FAKE_VALUE_FUNC19(                                                                 \
	RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,   \
	ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE,            \
	ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE)                    \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME)                                                \
		DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME)                                              \
		DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME)                                              \
		DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME)                                              \
		DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME)                                              \
		DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME)                                              \
		DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME)                                              \
		DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME)                                              \
		DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME)                                              \
		DECLARE_ARG(ARG18_TYPE, 18, FUNCNAME)                                              \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE)                                      \
		DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE)                                          \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE,       \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,       \
					     ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE,       \
					     ARG18_TYPE);                                          \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,  \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,       \
					     ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE,       \
					     ARG18_TYPE);                                          \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17,            \
		ARG18_TYPE arg18);

#define DEFINE_FAKE_VALUE_FUNC19(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, \
				 ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,        \
				 ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE)       \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17,            \
		ARG18_TYPE arg18)                                                                  \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		SAVE_ARG(FUNCNAME, 9);                                                             \
		SAVE_ARG(FUNCNAME, 10);                                                            \
		SAVE_ARG(FUNCNAME, 11);                                                            \
		SAVE_ARG(FUNCNAME, 12);                                                            \
		SAVE_ARG(FUNCNAME, 13);                                                            \
		SAVE_ARG(FUNCNAME, 14);                                                            \
		SAVE_ARG(FUNCNAME, 15);                                                            \
		SAVE_ARG(FUNCNAME, 16);                                                            \
		SAVE_ARG(FUNCNAME, 17);                                                            \
		SAVE_ARG(FUNCNAME, 18);                                                            \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 9);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 10);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 11);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 12);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 13);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 14);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 15);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 16);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 17);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 18);                                            \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_idx++](           \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							arg7, arg8, arg9, arg10, arg11, arg12,     \
							arg13, arg14, arg15, arg16, arg17, arg18); \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				return ret;                                                        \
			} else {                                                                   \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_len - 1](         \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							arg7, arg8, arg9, arg10, arg11, arg12,     \
							arg13, arg14, arg15, arg16, arg17, arg18); \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				return ret;                                                        \
				return FUNCNAME##_fake                                             \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12, arg13, arg14,     \
						arg15, arg16, arg17, arg18);                       \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake != NULL) {                                         \
			RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(                             \
				arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, \
				arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18);           \
			SAVE_RET_HISTORY(FUNCNAME, ret);                                           \
			return ret;                                                                \
			return FUNCNAME##_fake.custom_fake(                                        \
				arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, \
				arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18);           \
		}                                                                                  \
		RETURN_FAKE_RESULT(FUNCNAME)                                                       \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VALUE_FUNC19(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,       \
			  ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,        \
			  ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE,  \
			  ARG16_TYPE, ARG17_TYPE, ARG18_TYPE)                                      \
	DECLARE_FAKE_VALUE_FUNC19(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,          \
				  ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,           \
				  ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE,        \
				  ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE,      \
				  ARG18_TYPE)                                                      \
	DEFINE_FAKE_VALUE_FUNC19(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, \
				 ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,        \
				 ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE)

#define DECLARE_FAKE_VALUE_FUNC20(                                                                 \
	RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,   \
	ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE,            \
	ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE)        \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME)                                                \
		DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME)                                              \
		DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME)                                              \
		DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME)                                              \
		DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME)                                              \
		DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME)                                              \
		DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME)                                              \
		DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME)                                              \
		DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME)                                              \
		DECLARE_ARG(ARG18_TYPE, 18, FUNCNAME)                                              \
		DECLARE_ARG(ARG19_TYPE, 19, FUNCNAME)                                              \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE)                                      \
		DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE)                                          \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE,       \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,       \
					     ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE,       \
					     ARG18_TYPE, ARG19_TYPE);                              \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,  \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,       \
					     ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE,       \
					     ARG18_TYPE, ARG19_TYPE);                              \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17,            \
		ARG18_TYPE arg18, ARG19_TYPE arg19);

#define DEFINE_FAKE_VALUE_FUNC20(                                                                  \
	RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,   \
	ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE,            \
	ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE)        \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17,            \
		ARG18_TYPE arg18, ARG19_TYPE arg19)                                                \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		SAVE_ARG(FUNCNAME, 9);                                                             \
		SAVE_ARG(FUNCNAME, 10);                                                            \
		SAVE_ARG(FUNCNAME, 11);                                                            \
		SAVE_ARG(FUNCNAME, 12);                                                            \
		SAVE_ARG(FUNCNAME, 13);                                                            \
		SAVE_ARG(FUNCNAME, 14);                                                            \
		SAVE_ARG(FUNCNAME, 15);                                                            \
		SAVE_ARG(FUNCNAME, 16);                                                            \
		SAVE_ARG(FUNCNAME, 17);                                                            \
		SAVE_ARG(FUNCNAME, 18);                                                            \
		SAVE_ARG(FUNCNAME, 19);                                                            \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 9);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 10);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 11);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 12);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 13);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 14);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 15);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 16);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 17);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 18);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 19);                                            \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_idx++](           \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							arg7, arg8, arg9, arg10, arg11, arg12,     \
							arg13, arg14, arg15, arg16, arg17, arg18,  \
							arg19);                                    \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				return ret;                                                        \
			} else {                                                                   \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_len - 1](         \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							arg7, arg8, arg9, arg10, arg11, arg12,     \
							arg13, arg14, arg15, arg16, arg17, arg18,  \
							arg19);                                    \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				return ret;                                                        \
				return FUNCNAME##_fake                                             \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12, arg13, arg14,     \
						arg15, arg16, arg17, arg18, arg19);                \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake != NULL) {                                         \
			RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(                             \
				arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, \
				arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19);    \
			SAVE_RET_HISTORY(FUNCNAME, ret);                                           \
			return ret;                                                                \
			return FUNCNAME##_fake.custom_fake(                                        \
				arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, \
				arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19);    \
		}                                                                                  \
		RETURN_FAKE_RESULT(FUNCNAME)                                                       \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VALUE_FUNC20(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,       \
			  ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,        \
			  ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE,  \
			  ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE)                          \
	DECLARE_FAKE_VALUE_FUNC20(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,          \
				  ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,           \
				  ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE,        \
				  ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE,      \
				  ARG18_TYPE, ARG19_TYPE)                                          \
	DEFINE_FAKE_VALUE_FUNC20(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, \
				 ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,        \
				 ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE,       \
				 ARG19_TYPE)

#define DECLARE_FAKE_VOID_FUNC2_VARARG(FUNCNAME, ARG0_TYPE, ...)                                   \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, va_list ap);            \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, va_list ap);       \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ...);

#define DEFINE_FAKE_VOID_FUNC2_VARARG(FUNCNAME, ARG0_TYPE, ...)                                    \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ...)                             \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				va_list ap;                                                        \
				va_start(ap, arg0);                                                \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](   \
						arg0, ap);                                         \
				va_end(ap);                                                        \
			} else {                                                                   \
				va_list ap;                                                        \
				va_start(ap, arg0);                                                \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, ap);                                         \
				va_end(ap);                                                        \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake) {                                                 \
			va_list ap;                                                                \
			va_start(ap, arg0);                                                        \
			FUNCNAME##_fake.custom_fake(arg0, ap);                                     \
			va_end(ap);                                                                \
		}                                                                                  \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VOID_FUNC2_VARARG(FUNCNAME, ARG0_TYPE, ...)                                           \
	DECLARE_FAKE_VOID_FUNC2_VARARG(FUNCNAME, ARG0_TYPE, ...)                                   \
	DEFINE_FAKE_VOID_FUNC2_VARARG(FUNCNAME, ARG0_TYPE, ...)

#define DECLARE_FAKE_VOID_FUNC3_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...)                        \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, va_list ap); \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,         \
					     va_list ap);                                          \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ...);

#define DEFINE_FAKE_VOID_FUNC3_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...)                         \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ...)             \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				va_list ap;                                                        \
				va_start(ap, arg1);                                                \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](   \
						arg0, arg1, ap);                                   \
				va_end(ap);                                                        \
			} else {                                                                   \
				va_list ap;                                                        \
				va_start(ap, arg1);                                                \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, ap);                                   \
				va_end(ap);                                                        \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake) {                                                 \
			va_list ap;                                                                \
			va_start(ap, arg1);                                                        \
			FUNCNAME##_fake.custom_fake(arg0, arg1, ap);                               \
			va_end(ap);                                                                \
		}                                                                                  \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VOID_FUNC3_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...)                                \
	DECLARE_FAKE_VOID_FUNC3_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...)                        \
	DEFINE_FAKE_VOID_FUNC3_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...)

#define DECLARE_FAKE_VOID_FUNC4_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...)             \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					     va_list ap);                                          \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,         \
					     ARG2_TYPE, va_list ap);                               \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2,  \
						  ...);

#define DEFINE_FAKE_VOID_FUNC4_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...)              \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2,  \
						  ...)                                             \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				va_list ap;                                                        \
				va_start(ap, arg2);                                                \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](   \
						arg0, arg1, arg2, ap);                             \
				va_end(ap);                                                        \
			} else {                                                                   \
				va_list ap;                                                        \
				va_start(ap, arg2);                                                \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, ap);                             \
				va_end(ap);                                                        \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake) {                                                 \
			va_list ap;                                                                \
			va_start(ap, arg2);                                                        \
			FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, ap);                         \
			va_end(ap);                                                                \
		}                                                                                  \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VOID_FUNC4_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...)                     \
	DECLARE_FAKE_VOID_FUNC4_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...)             \
	DEFINE_FAKE_VOID_FUNC4_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...)

#define DECLARE_FAKE_VOID_FUNC5_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...)  \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					     ARG3_TYPE, va_list ap);                               \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,         \
					     ARG2_TYPE, ARG3_TYPE, va_list ap);                    \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2,  \
						  ARG3_TYPE arg3, ...);

#define DEFINE_FAKE_VOID_FUNC5_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...)   \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2,  \
						  ARG3_TYPE arg3, ...)                             \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				va_list ap;                                                        \
				va_start(ap, arg3);                                                \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](   \
						arg0, arg1, arg2, arg3, ap);                       \
				va_end(ap);                                                        \
			} else {                                                                   \
				va_list ap;                                                        \
				va_start(ap, arg3);                                                \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, ap);                       \
				va_end(ap);                                                        \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake) {                                                 \
			va_list ap;                                                                \
			va_start(ap, arg3);                                                        \
			FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, ap);                   \
			va_end(ap);                                                                \
		}                                                                                  \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VOID_FUNC5_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...)          \
	DECLARE_FAKE_VOID_FUNC5_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...)  \
	DEFINE_FAKE_VOID_FUNC5_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...)

#define DECLARE_FAKE_VOID_FUNC6_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,       \
				       ARG4_TYPE, ...)                                             \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					     ARG3_TYPE, ARG4_TYPE, va_list ap);                    \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,         \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, va_list ap);         \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2,  \
						  ARG3_TYPE arg3, ARG4_TYPE arg4, ...);

#define DEFINE_FAKE_VOID_FUNC6_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,        \
				      ARG4_TYPE, ...)                                              \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2,  \
						  ARG3_TYPE arg3, ARG4_TYPE arg4, ...)             \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				va_list ap;                                                        \
				va_start(ap, arg4);                                                \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](   \
						arg0, arg1, arg2, arg3, arg4, ap);                 \
				va_end(ap);                                                        \
			} else {                                                                   \
				va_list ap;                                                        \
				va_start(ap, arg4);                                                \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, ap);                 \
				va_end(ap);                                                        \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake) {                                                 \
			va_list ap;                                                                \
			va_start(ap, arg4);                                                        \
			FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, ap);             \
			va_end(ap);                                                                \
		}                                                                                  \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VOID_FUNC6_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,    \
			       ...)                                                                \
	DECLARE_FAKE_VOID_FUNC6_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,       \
				       ARG4_TYPE, ...)                                             \
	DEFINE_FAKE_VOID_FUNC6_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,        \
				      ARG4_TYPE, ...)

#define DECLARE_FAKE_VOID_FUNC7_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,       \
				       ARG4_TYPE, ARG5_TYPE, ...)                                  \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					     ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, va_list ap);         \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,         \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     va_list ap);                                          \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2,  \
						  ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5,  \
						  ...);

#define DEFINE_FAKE_VOID_FUNC7_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,        \
				      ARG4_TYPE, ARG5_TYPE, ...)                                   \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2,  \
						  ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5,  \
						  ...)                                             \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				va_list ap;                                                        \
				va_start(ap, arg5);                                                \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](   \
						arg0, arg1, arg2, arg3, arg4, arg5, ap);           \
				va_end(ap);                                                        \
			} else {                                                                   \
				va_list ap;                                                        \
				va_start(ap, arg5);                                                \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, ap);           \
				va_end(ap);                                                        \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake) {                                                 \
			va_list ap;                                                                \
			va_start(ap, arg5);                                                        \
			FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, ap);       \
			va_end(ap);                                                                \
		}                                                                                  \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VOID_FUNC7_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,    \
			       ARG5_TYPE, ...)                                                     \
	DECLARE_FAKE_VOID_FUNC7_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,       \
				       ARG4_TYPE, ARG5_TYPE, ...)                                  \
	DEFINE_FAKE_VOID_FUNC7_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,        \
				      ARG4_TYPE, ARG5_TYPE, ...)

#define DECLARE_FAKE_VOID_FUNC8_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,       \
				       ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...)                       \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					     ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE,           \
					     va_list ap);                                          \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,         \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, va_list ap);                               \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2,  \
						  ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5,  \
						  ARG6_TYPE arg6, ...);

#define DEFINE_FAKE_VOID_FUNC8_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,        \
				      ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...)                        \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2,  \
						  ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5,  \
						  ARG6_TYPE arg6, ...)                             \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				va_list ap;                                                        \
				va_start(ap, arg6);                                                \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](   \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, ap);     \
				va_end(ap);                                                        \
			} else {                                                                   \
				va_list ap;                                                        \
				va_start(ap, arg6);                                                \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, ap);     \
				va_end(ap);                                                        \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake) {                                                 \
			va_list ap;                                                                \
			va_start(ap, arg6);                                                        \
			FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, ap); \
			va_end(ap);                                                                \
		}                                                                                  \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VOID_FUNC8_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,    \
			       ARG5_TYPE, ARG6_TYPE, ...)                                          \
	DECLARE_FAKE_VOID_FUNC8_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,       \
				       ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...)                       \
	DEFINE_FAKE_VOID_FUNC8_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,        \
				      ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...)

#define DECLARE_FAKE_VOID_FUNC9_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,       \
				       ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...)            \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					     ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE,           \
					     ARG7_TYPE, va_list ap);                               \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,         \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, va_list ap);                    \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2,  \
						  ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5,  \
						  ARG6_TYPE arg6, ARG7_TYPE arg7, ...);

#define DEFINE_FAKE_VOID_FUNC9_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,        \
				      ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...)             \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2,  \
						  ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5,  \
						  ARG6_TYPE arg6, ARG7_TYPE arg7, ...)             \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				va_list ap;                                                        \
				va_start(ap, arg7);                                                \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](   \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						ap);                                               \
				va_end(ap);                                                        \
			} else {                                                                   \
				va_list ap;                                                        \
				va_start(ap, arg7);                                                \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						ap);                                               \
				va_end(ap);                                                        \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake) {                                                 \
			va_list ap;                                                                \
			va_start(ap, arg7);                                                        \
			FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6,      \
						    arg7, ap);                                     \
			va_end(ap);                                                                \
		}                                                                                  \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VOID_FUNC9_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,    \
			       ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...)                               \
	DECLARE_FAKE_VOID_FUNC9_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,       \
				       ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...)            \
	DEFINE_FAKE_VOID_FUNC9_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,        \
				      ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...)

#define DECLARE_FAKE_VOID_FUNC10_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,      \
					ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE,     \
					...)                                                       \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					     ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE,           \
					     ARG7_TYPE, ARG8_TYPE, va_list ap);                    \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,         \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, va_list ap);         \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                                 \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ...);

#define DEFINE_FAKE_VOID_FUNC10_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,       \
				       ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                                 \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ...)               \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				va_list ap;                                                        \
				va_start(ap, arg8);                                                \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](   \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, ap);                                         \
				va_end(ap);                                                        \
			} else {                                                                   \
				va_list ap;                                                        \
				va_start(ap, arg8);                                                \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, ap);                                         \
				va_end(ap);                                                        \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake) {                                                 \
			va_list ap;                                                                \
			va_start(ap, arg8);                                                        \
			FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6,      \
						    arg7, arg8, ap);                               \
			va_end(ap);                                                                \
		}                                                                                  \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VOID_FUNC10_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,   \
				ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...)                   \
	DECLARE_FAKE_VOID_FUNC10_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,      \
					ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE,     \
					...)                                                       \
	DEFINE_FAKE_VOID_FUNC10_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,       \
				       ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...)

#define DECLARE_FAKE_VOID_FUNC11_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,      \
					ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE,     \
					ARG9_TYPE, ...)                                            \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME)                                                \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					     ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE,           \
					     ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, va_list ap);         \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,         \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     va_list ap);                                          \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2,  \
						  ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5,  \
						  ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8,  \
						  ARG9_TYPE arg9, ...);

#define DEFINE_FAKE_VOID_FUNC11_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,       \
				       ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE,      \
				       ARG9_TYPE, ...)                                             \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2,  \
						  ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5,  \
						  ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8,  \
						  ARG9_TYPE arg9, ...)                             \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		SAVE_ARG(FUNCNAME, 9);                                                             \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 9);                                             \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				va_list ap;                                                        \
				va_start(ap, arg9);                                                \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](   \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, ap);                                   \
				va_end(ap);                                                        \
			} else {                                                                   \
				va_list ap;                                                        \
				va_start(ap, arg9);                                                \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, ap);                                   \
				va_end(ap);                                                        \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake) {                                                 \
			va_list ap;                                                                \
			va_start(ap, arg9);                                                        \
			FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6,      \
						    arg7, arg8, arg9, ap);                         \
			va_end(ap);                                                                \
		}                                                                                  \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VOID_FUNC11_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,   \
				ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...)        \
	DECLARE_FAKE_VOID_FUNC11_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,      \
					ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE,     \
					ARG9_TYPE, ...)                                            \
	DEFINE_FAKE_VOID_FUNC11_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,       \
				       ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE,      \
				       ARG9_TYPE, ...)

#define DECLARE_FAKE_VOID_FUNC12_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,      \
					ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE,     \
					ARG9_TYPE, ARG10_TYPE, ...)                                \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME)                                                \
		DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME)                                              \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					     ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE,           \
					     ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE,          \
					     va_list ap);                                          \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,         \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, va_list ap);                              \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2,  \
						  ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5,  \
						  ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8,  \
						  ARG9_TYPE arg9, ARG10_TYPE arg10, ...);

#define DEFINE_FAKE_VOID_FUNC12_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,       \
				       ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE,      \
				       ARG9_TYPE, ARG10_TYPE, ...)                                 \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2,  \
						  ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5,  \
						  ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8,  \
						  ARG9_TYPE arg9, ARG10_TYPE arg10, ...)           \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		SAVE_ARG(FUNCNAME, 9);                                                             \
		SAVE_ARG(FUNCNAME, 10);                                                            \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 9);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 10);                                            \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				va_list ap;                                                        \
				va_start(ap, arg10);                                               \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](   \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, ap);                            \
				va_end(ap);                                                        \
			} else {                                                                   \
				va_list ap;                                                        \
				va_start(ap, arg10);                                               \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, ap);                            \
				va_end(ap);                                                        \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake) {                                                 \
			va_list ap;                                                                \
			va_start(ap, arg10);                                                       \
			FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6,      \
						    arg7, arg8, arg9, arg10, ap);                  \
			va_end(ap);                                                                \
		}                                                                                  \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VOID_FUNC12_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,   \
				ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, \
				...)                                                               \
	DECLARE_FAKE_VOID_FUNC12_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,      \
					ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE,     \
					ARG9_TYPE, ARG10_TYPE, ...)                                \
	DEFINE_FAKE_VOID_FUNC12_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,       \
				       ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE,      \
				       ARG9_TYPE, ARG10_TYPE, ...)

#define DECLARE_FAKE_VOID_FUNC13_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,      \
					ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE,     \
					ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...)                    \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME)                                                \
		DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME)                                              \
		DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME)                                              \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					     ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE,           \
					     ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE,          \
					     ARG11_TYPE, va_list ap);                              \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,         \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, va_list ap);                  \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                                 \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ...);

#define DEFINE_FAKE_VOID_FUNC13_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,       \
				       ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE,      \
				       ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...)                     \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                                 \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ...)                                           \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		SAVE_ARG(FUNCNAME, 9);                                                             \
		SAVE_ARG(FUNCNAME, 10);                                                            \
		SAVE_ARG(FUNCNAME, 11);                                                            \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 9);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 10);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 11);                                            \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				va_list ap;                                                        \
				va_start(ap, arg11);                                               \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](   \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, ap);                     \
				va_end(ap);                                                        \
			} else {                                                                   \
				va_list ap;                                                        \
				va_start(ap, arg11);                                               \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, ap);                     \
				va_end(ap);                                                        \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake) {                                                 \
			va_list ap;                                                                \
			va_start(ap, arg11);                                                       \
			FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6,      \
						    arg7, arg8, arg9, arg10, arg11, ap);           \
			va_end(ap);                                                                \
		}                                                                                  \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VOID_FUNC13_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,   \
				ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, \
				ARG11_TYPE, ...)                                                   \
	DECLARE_FAKE_VOID_FUNC13_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,      \
					ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE,     \
					ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...)                    \
	DEFINE_FAKE_VOID_FUNC13_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,       \
				       ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE,      \
				       ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...)

#define DECLARE_FAKE_VOID_FUNC14_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,      \
					ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE,     \
					ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...)        \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME)                                                \
		DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME)                                              \
		DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME)                                              \
		DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME)                                              \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					     ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE,           \
					     ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE,          \
					     ARG11_TYPE, ARG12_TYPE, va_list ap);                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,         \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, va_list ap);      \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                                 \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ...);

#define DEFINE_FAKE_VOID_FUNC14_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,       \
				       ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE,      \
				       ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...)         \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                                 \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ...)                         \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		SAVE_ARG(FUNCNAME, 9);                                                             \
		SAVE_ARG(FUNCNAME, 10);                                                            \
		SAVE_ARG(FUNCNAME, 11);                                                            \
		SAVE_ARG(FUNCNAME, 12);                                                            \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 9);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 10);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 11);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 12);                                            \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				va_list ap;                                                        \
				va_start(ap, arg12);                                               \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](   \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12, ap);              \
				va_end(ap);                                                        \
			} else {                                                                   \
				va_list ap;                                                        \
				va_start(ap, arg12);                                               \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12, ap);              \
				va_end(ap);                                                        \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake) {                                                 \
			va_list ap;                                                                \
			va_start(ap, arg12);                                                       \
			FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6,      \
						    arg7, arg8, arg9, arg10, arg11, arg12, ap);    \
			va_end(ap);                                                                \
		}                                                                                  \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VOID_FUNC14_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,   \
				ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, \
				ARG11_TYPE, ARG12_TYPE, ...)                                       \
	DECLARE_FAKE_VOID_FUNC14_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,      \
					ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE,     \
					ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...)        \
	DEFINE_FAKE_VOID_FUNC14_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,       \
				       ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE,      \
				       ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...)

#define DECLARE_FAKE_VOID_FUNC15_VARARG(                                                           \
	FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE,     \
	ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...)      \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME)                                                \
		DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME)                                              \
		DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME)                                              \
		DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME)                                              \
		DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME)                                              \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					     ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE,           \
					     ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE,          \
					     ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, va_list ap);      \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,         \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,       \
					     va_list ap);                                          \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                                 \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ...);

#define DEFINE_FAKE_VOID_FUNC15_VARARG(                                                            \
	FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE,     \
	ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...)      \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                                 \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ...)       \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		SAVE_ARG(FUNCNAME, 9);                                                             \
		SAVE_ARG(FUNCNAME, 10);                                                            \
		SAVE_ARG(FUNCNAME, 11);                                                            \
		SAVE_ARG(FUNCNAME, 12);                                                            \
		SAVE_ARG(FUNCNAME, 13);                                                            \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 9);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 10);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 11);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 12);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 13);                                            \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				va_list ap;                                                        \
				va_start(ap, arg13);                                               \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](   \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12, arg13, ap);       \
				va_end(ap);                                                        \
			} else {                                                                   \
				va_list ap;                                                        \
				va_start(ap, arg13);                                               \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12, arg13, ap);       \
				va_end(ap);                                                        \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake) {                                                 \
			va_list ap;                                                                \
			va_start(ap, arg13);                                                       \
			FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6,      \
						    arg7, arg8, arg9, arg10, arg11, arg12, arg13,  \
						    ap);                                           \
			va_end(ap);                                                                \
		}                                                                                  \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VOID_FUNC15_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,   \
				ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, \
				ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...)                           \
	DECLARE_FAKE_VOID_FUNC15_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,      \
					ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE,     \
					ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, \
					...)                                                       \
	DEFINE_FAKE_VOID_FUNC15_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,       \
				       ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE,      \
				       ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,  \
				       ...)

#define DECLARE_FAKE_VOID_FUNC16_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,      \
					ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE,     \
					ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, \
					ARG14_TYPE, ...)                                           \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME)                                                \
		DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME)                                              \
		DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME)                                              \
		DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME)                                              \
		DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME)                                              \
		DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME)                                              \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					     ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE,           \
					     ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE,          \
					     ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE,       \
					     va_list ap);                                          \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,         \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,       \
					     ARG14_TYPE, va_list ap);                              \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                                 \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14, ...);

#define DEFINE_FAKE_VOID_FUNC16_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,       \
				       ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE,      \
				       ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,  \
				       ARG14_TYPE, ...)                                            \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                                 \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14, ...)                                                             \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		SAVE_ARG(FUNCNAME, 9);                                                             \
		SAVE_ARG(FUNCNAME, 10);                                                            \
		SAVE_ARG(FUNCNAME, 11);                                                            \
		SAVE_ARG(FUNCNAME, 12);                                                            \
		SAVE_ARG(FUNCNAME, 13);                                                            \
		SAVE_ARG(FUNCNAME, 14);                                                            \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 9);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 10);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 11);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 12);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 13);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 14);                                            \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				va_list ap;                                                        \
				va_start(ap, arg14);                                               \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](   \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12, arg13, arg14,     \
						ap);                                               \
				va_end(ap);                                                        \
			} else {                                                                   \
				va_list ap;                                                        \
				va_start(ap, arg14);                                               \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12, arg13, arg14,     \
						ap);                                               \
				va_end(ap);                                                        \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake) {                                                 \
			va_list ap;                                                                \
			va_start(ap, arg14);                                                       \
			FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6,      \
						    arg7, arg8, arg9, arg10, arg11, arg12, arg13,  \
						    arg14, ap);                                    \
			va_end(ap);                                                                \
		}                                                                                  \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VOID_FUNC16_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,   \
				ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, \
				ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...)               \
	DECLARE_FAKE_VOID_FUNC16_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,      \
					ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE,     \
					ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, \
					ARG14_TYPE, ...)                                           \
	DEFINE_FAKE_VOID_FUNC16_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,       \
				       ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE,      \
				       ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,  \
				       ARG14_TYPE, ...)

#define DECLARE_FAKE_VOID_FUNC17_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,      \
					ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE,     \
					ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, \
					ARG14_TYPE, ARG15_TYPE, ...)                               \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME)                                                \
		DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME)                                              \
		DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME)                                              \
		DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME)                                              \
		DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME)                                              \
		DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME)                                              \
		DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME)                                              \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					     ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE,           \
					     ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE,          \
					     ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE,       \
					     ARG15_TYPE, va_list ap);                              \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,         \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,       \
					     ARG14_TYPE, ARG15_TYPE, va_list ap);                  \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                                 \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14, ARG15_TYPE arg15, ...);

#define DEFINE_FAKE_VOID_FUNC17_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,       \
				       ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE,      \
				       ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,  \
				       ARG14_TYPE, ARG15_TYPE, ...)                                \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                                 \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14, ARG15_TYPE arg15, ...)                                           \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		SAVE_ARG(FUNCNAME, 9);                                                             \
		SAVE_ARG(FUNCNAME, 10);                                                            \
		SAVE_ARG(FUNCNAME, 11);                                                            \
		SAVE_ARG(FUNCNAME, 12);                                                            \
		SAVE_ARG(FUNCNAME, 13);                                                            \
		SAVE_ARG(FUNCNAME, 14);                                                            \
		SAVE_ARG(FUNCNAME, 15);                                                            \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 9);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 10);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 11);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 12);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 13);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 14);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 15);                                            \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				va_list ap;                                                        \
				va_start(ap, arg15);                                               \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](   \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12, arg13, arg14,     \
						arg15, ap);                                        \
				va_end(ap);                                                        \
			} else {                                                                   \
				va_list ap;                                                        \
				va_start(ap, arg15);                                               \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12, arg13, arg14,     \
						arg15, ap);                                        \
				va_end(ap);                                                        \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake) {                                                 \
			va_list ap;                                                                \
			va_start(ap, arg15);                                                       \
			FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6,      \
						    arg7, arg8, arg9, arg10, arg11, arg12, arg13,  \
						    arg14, arg15, ap);                             \
			va_end(ap);                                                                \
		}                                                                                  \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VOID_FUNC17_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,   \
				ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, \
				ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...)   \
	DECLARE_FAKE_VOID_FUNC17_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,      \
					ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE,     \
					ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, \
					ARG14_TYPE, ARG15_TYPE, ...)                               \
	DEFINE_FAKE_VOID_FUNC17_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,       \
				       ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE,      \
				       ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,  \
				       ARG14_TYPE, ARG15_TYPE, ...)

#define DECLARE_FAKE_VOID_FUNC18_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,      \
					ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE,     \
					ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, \
					ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...)                   \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME)                                                \
		DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME)                                              \
		DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME)                                              \
		DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME)                                              \
		DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME)                                              \
		DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME)                                              \
		DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME)                                              \
		DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME)                                              \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					     ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE,           \
					     ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE,          \
					     ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE,       \
					     ARG15_TYPE, ARG16_TYPE, va_list ap);                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,         \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,       \
					     ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, va_list ap);      \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                                 \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ...);

#define DEFINE_FAKE_VOID_FUNC18_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,       \
				       ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE,      \
				       ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,  \
				       ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...)                    \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                                 \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ...)                         \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		SAVE_ARG(FUNCNAME, 9);                                                             \
		SAVE_ARG(FUNCNAME, 10);                                                            \
		SAVE_ARG(FUNCNAME, 11);                                                            \
		SAVE_ARG(FUNCNAME, 12);                                                            \
		SAVE_ARG(FUNCNAME, 13);                                                            \
		SAVE_ARG(FUNCNAME, 14);                                                            \
		SAVE_ARG(FUNCNAME, 15);                                                            \
		SAVE_ARG(FUNCNAME, 16);                                                            \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 9);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 10);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 11);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 12);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 13);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 14);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 15);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 16);                                            \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				va_list ap;                                                        \
				va_start(ap, arg16);                                               \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](   \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12, arg13, arg14,     \
						arg15, arg16, ap);                                 \
				va_end(ap);                                                        \
			} else {                                                                   \
				va_list ap;                                                        \
				va_start(ap, arg16);                                               \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12, arg13, arg14,     \
						arg15, arg16, ap);                                 \
				va_end(ap);                                                        \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake) {                                                 \
			va_list ap;                                                                \
			va_start(ap, arg16);                                                       \
			FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6,      \
						    arg7, arg8, arg9, arg10, arg11, arg12, arg13,  \
						    arg14, arg15, arg16, ap);                      \
			va_end(ap);                                                                \
		}                                                                                  \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VOID_FUNC18_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,   \
				ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, \
				ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE,        \
				ARG16_TYPE, ...)                                                   \
	DECLARE_FAKE_VOID_FUNC18_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,      \
					ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE,     \
					ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, \
					ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...)                   \
	DEFINE_FAKE_VOID_FUNC18_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,       \
				       ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE,      \
				       ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,  \
				       ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...)

#define DECLARE_FAKE_VOID_FUNC19_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,      \
					ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE,     \
					ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, \
					ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...)       \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME)                                                \
		DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME)                                              \
		DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME)                                              \
		DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME)                                              \
		DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME)                                              \
		DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME)                                              \
		DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME)                                              \
		DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME)                                              \
		DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME)                                              \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					     ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE,           \
					     ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE,          \
					     ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE,       \
					     ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, va_list ap);      \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,         \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,       \
					     ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE,       \
					     va_list ap);                                          \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                                 \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ...);

#define DEFINE_FAKE_VOID_FUNC19_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,       \
				       ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE,      \
				       ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,  \
				       ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...)        \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                                 \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ...)       \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		SAVE_ARG(FUNCNAME, 9);                                                             \
		SAVE_ARG(FUNCNAME, 10);                                                            \
		SAVE_ARG(FUNCNAME, 11);                                                            \
		SAVE_ARG(FUNCNAME, 12);                                                            \
		SAVE_ARG(FUNCNAME, 13);                                                            \
		SAVE_ARG(FUNCNAME, 14);                                                            \
		SAVE_ARG(FUNCNAME, 15);                                                            \
		SAVE_ARG(FUNCNAME, 16);                                                            \
		SAVE_ARG(FUNCNAME, 17);                                                            \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 9);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 10);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 11);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 12);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 13);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 14);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 15);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 16);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 17);                                            \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				va_list ap;                                                        \
				va_start(ap, arg17);                                               \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](   \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12, arg13, arg14,     \
						arg15, arg16, arg17, ap);                          \
				va_end(ap);                                                        \
			} else {                                                                   \
				va_list ap;                                                        \
				va_start(ap, arg17);                                               \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12, arg13, arg14,     \
						arg15, arg16, arg17, ap);                          \
				va_end(ap);                                                        \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake) {                                                 \
			va_list ap;                                                                \
			va_start(ap, arg17);                                                       \
			FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6,      \
						    arg7, arg8, arg9, arg10, arg11, arg12, arg13,  \
						    arg14, arg15, arg16, arg17, ap);               \
			va_end(ap);                                                                \
		}                                                                                  \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VOID_FUNC19_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,   \
				ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, \
				ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE,        \
				ARG16_TYPE, ARG17_TYPE, ...)                                       \
	DECLARE_FAKE_VOID_FUNC19_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,      \
					ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE,     \
					ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, \
					ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...)       \
	DEFINE_FAKE_VOID_FUNC19_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE,       \
				       ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE,      \
				       ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,  \
				       ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...)

#define DECLARE_FAKE_VOID_FUNC20_VARARG(                                                           \
	FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE,     \
	ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,           \
	ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...)                           \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME)                                                \
		DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME)                                              \
		DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME)                                              \
		DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME)                                              \
		DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME)                                              \
		DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME)                                              \
		DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME)                                              \
		DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME)                                              \
		DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME)                                              \
		DECLARE_ARG(ARG18_TYPE, 18, FUNCNAME)                                              \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					     ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE,           \
					     ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE,          \
					     ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE,       \
					     ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE,       \
					     va_list ap);                                          \
		CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,         \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,       \
					     ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE,       \
					     ARG18_TYPE, va_list ap);                              \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                                 \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17,            \
		ARG18_TYPE arg18, ...);

#define DEFINE_FAKE_VOID_FUNC20_VARARG(                                                            \
	FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE,     \
	ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,           \
	ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...)                           \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                                 \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17,            \
		ARG18_TYPE arg18, ...)                                                             \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		SAVE_ARG(FUNCNAME, 9);                                                             \
		SAVE_ARG(FUNCNAME, 10);                                                            \
		SAVE_ARG(FUNCNAME, 11);                                                            \
		SAVE_ARG(FUNCNAME, 12);                                                            \
		SAVE_ARG(FUNCNAME, 13);                                                            \
		SAVE_ARG(FUNCNAME, 14);                                                            \
		SAVE_ARG(FUNCNAME, 15);                                                            \
		SAVE_ARG(FUNCNAME, 16);                                                            \
		SAVE_ARG(FUNCNAME, 17);                                                            \
		SAVE_ARG(FUNCNAME, 18);                                                            \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 9);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 10);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 11);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 12);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 13);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 14);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 15);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 16);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 17);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 18);                                            \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				va_list ap;                                                        \
				va_start(ap, arg18);                                               \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](   \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12, arg13, arg14,     \
						arg15, arg16, arg17, arg18, ap);                   \
				va_end(ap);                                                        \
			} else {                                                                   \
				va_list ap;                                                        \
				va_start(ap, arg18);                                               \
				FUNCNAME##_fake                                                    \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12, arg13, arg14,     \
						arg15, arg16, arg17, arg18, ap);                   \
				va_end(ap);                                                        \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake) {                                                 \
			va_list ap;                                                                \
			va_start(ap, arg18);                                                       \
			FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6,      \
						    arg7, arg8, arg9, arg10, arg11, arg12, arg13,  \
						    arg14, arg15, arg16, arg17, arg18, ap);        \
			va_end(ap);                                                                \
		}                                                                                  \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VOID_FUNC20_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,   \
				ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, \
				ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE,        \
				ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...)                           \
	DECLARE_FAKE_VOID_FUNC20_VARARG(                                                           \
		FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,        \
		ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE,    \
		ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...)       \
	DEFINE_FAKE_VOID_FUNC20_VARARG(                                                            \
		FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,        \
		ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE,    \
		ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...)

#define DECLARE_FAKE_VALUE_FUNC2_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ...)                     \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE)                                      \
		DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE)                                          \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, va_list ap);     \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE,             \
					     va_list ap);                                          \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ...);

#define DEFINE_FAKE_VALUE_FUNC2_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ...)                      \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ...)                      \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				va_list ap;                                                        \
				va_start(ap, arg0);                                                \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, ap); \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				va_end(ap);                                                        \
				return ret;                                                        \
			} else {                                                                   \
				va_list ap;                                                        \
				va_start(ap, arg0);                                                \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_len - 1](arg0,    \
											  ap);     \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				va_end(ap);                                                        \
				return ret;                                                        \
				return FUNCNAME##_fake                                             \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, ap);                                         \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake) {                                                 \
			RETURN_TYPE ret;                                                           \
			va_list ap;                                                                \
			va_start(ap, arg0);                                                        \
			ret = FUNCNAME##_fake.custom_fake(arg0, ap);                               \
			va_end(ap);                                                                \
			SAVE_RET_HISTORY(FUNCNAME, ret);                                           \
			return ret;                                                                \
		}                                                                                  \
		RETURN_FAKE_RESULT(FUNCNAME)                                                       \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VALUE_FUNC2_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ...)                             \
	DECLARE_FAKE_VALUE_FUNC2_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ...)                     \
	DEFINE_FAKE_VALUE_FUNC2_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ...)

#define DECLARE_FAKE_VALUE_FUNC3_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...)          \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE)                                      \
		DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE)                                          \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE,       \
					     va_list ap);                                          \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,  \
					     va_list ap);                                          \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ...);

#define DEFINE_FAKE_VALUE_FUNC3_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...)           \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ...)      \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				va_list ap;                                                        \
				va_start(ap, arg1);                                                \
				RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq                  \
							  [FUNCNAME##_fake.custom_fake_seq_idx++]( \
								  arg0, arg1, ap);                 \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				va_end(ap);                                                        \
				return ret;                                                        \
			} else {                                                                   \
				va_list ap;                                                        \
				va_start(ap, arg1);                                                \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_len - 1](         \
							arg0, arg1, ap);                           \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				va_end(ap);                                                        \
				return ret;                                                        \
				return FUNCNAME##_fake                                             \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, ap);                                   \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake) {                                                 \
			RETURN_TYPE ret;                                                           \
			va_list ap;                                                                \
			va_start(ap, arg1);                                                        \
			ret = FUNCNAME##_fake.custom_fake(arg0, arg1, ap);                         \
			va_end(ap);                                                                \
			SAVE_RET_HISTORY(FUNCNAME, ret);                                           \
			return ret;                                                                \
		}                                                                                  \
		RETURN_FAKE_RESULT(FUNCNAME)                                                       \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VALUE_FUNC3_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...)                  \
	DECLARE_FAKE_VALUE_FUNC3_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...)          \
	DEFINE_FAKE_VALUE_FUNC3_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...)

#define DECLARE_FAKE_VALUE_FUNC4_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,    \
					...)                                                       \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE)                                      \
		DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE)                                          \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE,       \
					     ARG2_TYPE, va_list ap);                               \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,  \
					     ARG2_TYPE, va_list ap);                               \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1,           \
							 ARG2_TYPE arg2, ...);

#define DEFINE_FAKE_VALUE_FUNC4_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,     \
				       ...)                                                        \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1,           \
							 ARG2_TYPE arg2, ...)                      \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				va_list ap;                                                        \
				va_start(ap, arg2);                                                \
				RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq                  \
							  [FUNCNAME##_fake.custom_fake_seq_idx++]( \
								  arg0, arg1, arg2, ap);           \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				va_end(ap);                                                        \
				return ret;                                                        \
			} else {                                                                   \
				va_list ap;                                                        \
				va_start(ap, arg2);                                                \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_len - 1](         \
							arg0, arg1, arg2, ap);                     \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				va_end(ap);                                                        \
				return ret;                                                        \
				return FUNCNAME##_fake                                             \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, ap);                             \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake) {                                                 \
			RETURN_TYPE ret;                                                           \
			va_list ap;                                                                \
			va_start(ap, arg2);                                                        \
			ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, ap);                   \
			va_end(ap);                                                                \
			SAVE_RET_HISTORY(FUNCNAME, ret);                                           \
			return ret;                                                                \
		}                                                                                  \
		RETURN_FAKE_RESULT(FUNCNAME)                                                       \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VALUE_FUNC4_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...)       \
	DECLARE_FAKE_VALUE_FUNC4_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,    \
					...)                                                       \
	DEFINE_FAKE_VALUE_FUNC4_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...)

#define DECLARE_FAKE_VALUE_FUNC5_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,    \
					ARG3_TYPE, ...)                                            \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE)                                      \
		DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE)                                          \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE,       \
					     ARG2_TYPE, ARG3_TYPE, va_list ap);                    \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,  \
					     ARG2_TYPE, ARG3_TYPE, va_list ap);                    \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1,           \
							 ARG2_TYPE arg2, ARG3_TYPE arg3, ...);

#define DEFINE_FAKE_VALUE_FUNC5_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,     \
				       ARG3_TYPE, ...)                                             \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1,           \
							 ARG2_TYPE arg2, ARG3_TYPE arg3, ...)      \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				va_list ap;                                                        \
				va_start(ap, arg3);                                                \
				RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq                  \
							  [FUNCNAME##_fake.custom_fake_seq_idx++]( \
								  arg0, arg1, arg2, arg3, ap);     \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				va_end(ap);                                                        \
				return ret;                                                        \
			} else {                                                                   \
				va_list ap;                                                        \
				va_start(ap, arg3);                                                \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_len - 1](         \
							arg0, arg1, arg2, arg3, ap);               \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				va_end(ap);                                                        \
				return ret;                                                        \
				return FUNCNAME##_fake                                             \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, ap);                       \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake) {                                                 \
			RETURN_TYPE ret;                                                           \
			va_list ap;                                                                \
			va_start(ap, arg3);                                                        \
			ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, ap);             \
			va_end(ap);                                                                \
			SAVE_RET_HISTORY(FUNCNAME, ret);                                           \
			return ret;                                                                \
		}                                                                                  \
		RETURN_FAKE_RESULT(FUNCNAME)                                                       \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VALUE_FUNC5_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, \
				...)                                                               \
	DECLARE_FAKE_VALUE_FUNC5_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,    \
					ARG3_TYPE, ...)                                            \
	DEFINE_FAKE_VALUE_FUNC5_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,     \
				       ARG3_TYPE, ...)

#define DECLARE_FAKE_VALUE_FUNC6_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,    \
					ARG3_TYPE, ARG4_TYPE, ...)                                 \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE)                                      \
		DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE)                                          \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE,       \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, va_list ap);         \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,  \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, va_list ap);         \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1,           \
							 ARG2_TYPE arg2, ARG3_TYPE arg3,           \
							 ARG4_TYPE arg4, ...);

#define DEFINE_FAKE_VALUE_FUNC6_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,     \
				       ARG3_TYPE, ARG4_TYPE, ...)                                  \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1,           \
							 ARG2_TYPE arg2, ARG3_TYPE arg3,           \
							 ARG4_TYPE arg4, ...)                      \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				va_list ap;                                                        \
				va_start(ap, arg4);                                                \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_idx++](           \
							arg0, arg1, arg2, arg3, arg4, ap);         \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				va_end(ap);                                                        \
				return ret;                                                        \
			} else {                                                                   \
				va_list ap;                                                        \
				va_start(ap, arg4);                                                \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_len - 1](         \
							arg0, arg1, arg2, arg3, arg4, ap);         \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				va_end(ap);                                                        \
				return ret;                                                        \
				return FUNCNAME##_fake                                             \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, ap);                 \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake) {                                                 \
			RETURN_TYPE ret;                                                           \
			va_list ap;                                                                \
			va_start(ap, arg4);                                                        \
			ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, ap);       \
			va_end(ap);                                                                \
			SAVE_RET_HISTORY(FUNCNAME, ret);                                           \
			return ret;                                                                \
		}                                                                                  \
		RETURN_FAKE_RESULT(FUNCNAME)                                                       \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VALUE_FUNC6_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, \
				ARG4_TYPE, ...)                                                    \
	DECLARE_FAKE_VALUE_FUNC6_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,    \
					ARG3_TYPE, ARG4_TYPE, ...)                                 \
	DEFINE_FAKE_VALUE_FUNC6_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,     \
				       ARG3_TYPE, ARG4_TYPE, ...)

#define DECLARE_FAKE_VALUE_FUNC7_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,    \
					ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...)                      \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE)                                      \
		DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE)                                          \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE,       \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     va_list ap);                                          \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,  \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     va_list ap);                                          \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1,           \
							 ARG2_TYPE arg2, ARG3_TYPE arg3,           \
							 ARG4_TYPE arg4, ARG5_TYPE arg5, ...);

#define DEFINE_FAKE_VALUE_FUNC7_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,     \
				       ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...)                       \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1,           \
							 ARG2_TYPE arg2, ARG3_TYPE arg3,           \
							 ARG4_TYPE arg4, ARG5_TYPE arg5, ...)      \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				va_list ap;                                                        \
				va_start(ap, arg5);                                                \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_idx++](           \
							arg0, arg1, arg2, arg3, arg4, arg5, ap);   \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				va_end(ap);                                                        \
				return ret;                                                        \
			} else {                                                                   \
				va_list ap;                                                        \
				va_start(ap, arg5);                                                \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_len - 1](         \
							arg0, arg1, arg2, arg3, arg4, arg5, ap);   \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				va_end(ap);                                                        \
				return ret;                                                        \
				return FUNCNAME##_fake                                             \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, ap);           \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake) {                                                 \
			RETURN_TYPE ret;                                                           \
			va_list ap;                                                                \
			va_start(ap, arg5);                                                        \
			ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, ap); \
			va_end(ap);                                                                \
			SAVE_RET_HISTORY(FUNCNAME, ret);                                           \
			return ret;                                                                \
		}                                                                                  \
		RETURN_FAKE_RESULT(FUNCNAME)                                                       \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VALUE_FUNC7_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, \
				ARG4_TYPE, ARG5_TYPE, ...)                                         \
	DECLARE_FAKE_VALUE_FUNC7_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,    \
					ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...)                      \
	DEFINE_FAKE_VALUE_FUNC7_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,     \
				       ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...)

#define DECLARE_FAKE_VALUE_FUNC8_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,    \
					ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...)           \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE)                                      \
		DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE)                                          \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE,       \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, va_list ap);                               \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,  \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, va_list ap);                               \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ...);

#define DEFINE_FAKE_VALUE_FUNC8_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,     \
				       ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...)            \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ...)                                               \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				va_list ap;                                                        \
				va_start(ap, arg6);                                                \
				RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq                  \
							  [FUNCNAME##_fake.custom_fake_seq_idx++]( \
								  arg0, arg1, arg2, arg3, arg4,    \
								  arg5, arg6, ap);                 \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				va_end(ap);                                                        \
				return ret;                                                        \
			} else {                                                                   \
				va_list ap;                                                        \
				va_start(ap, arg6);                                                \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_len - 1](         \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							ap);                                       \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				va_end(ap);                                                        \
				return ret;                                                        \
				return FUNCNAME##_fake                                             \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, ap);     \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake) {                                                 \
			RETURN_TYPE ret;                                                           \
			va_list ap;                                                                \
			va_start(ap, arg6);                                                        \
			ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5,      \
							  arg6, ap);                               \
			va_end(ap);                                                                \
			SAVE_RET_HISTORY(FUNCNAME, ret);                                           \
			return ret;                                                                \
		}                                                                                  \
		RETURN_FAKE_RESULT(FUNCNAME)                                                       \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VALUE_FUNC8_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, \
				ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...)                              \
	DECLARE_FAKE_VALUE_FUNC8_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,    \
					ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...)           \
	DEFINE_FAKE_VALUE_FUNC8_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,     \
				       ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...)

#define DECLARE_FAKE_VALUE_FUNC9_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,    \
					ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,     \
					...)                                                       \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE)                                      \
		DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE)                                          \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE,       \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, va_list ap);                    \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,  \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, va_list ap);                    \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ...);

#define DEFINE_FAKE_VALUE_FUNC9_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,     \
				       ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ...)                               \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				va_list ap;                                                        \
				va_start(ap, arg7);                                                \
				RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq                  \
							  [FUNCNAME##_fake.custom_fake_seq_idx++]( \
								  arg0, arg1, arg2, arg3, arg4,    \
								  arg5, arg6, arg7, ap);           \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				va_end(ap);                                                        \
				return ret;                                                        \
			} else {                                                                   \
				va_list ap;                                                        \
				va_start(ap, arg7);                                                \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_len - 1](         \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							arg7, ap);                                 \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				va_end(ap);                                                        \
				return ret;                                                        \
				return FUNCNAME##_fake                                             \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						ap);                                               \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake) {                                                 \
			RETURN_TYPE ret;                                                           \
			va_list ap;                                                                \
			va_start(ap, arg7);                                                        \
			ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5,      \
							  arg6, arg7, ap);                         \
			va_end(ap);                                                                \
			SAVE_RET_HISTORY(FUNCNAME, ret);                                           \
			return ret;                                                                \
		}                                                                                  \
		RETURN_FAKE_RESULT(FUNCNAME)                                                       \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VALUE_FUNC9_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, \
				ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...)                   \
	DECLARE_FAKE_VALUE_FUNC9_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,    \
					ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,     \
					...)                                                       \
	DEFINE_FAKE_VALUE_FUNC9_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,     \
				       ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...)

#define DECLARE_FAKE_VALUE_FUNC10_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,    \
					 ARG8_TYPE, ...)                                           \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE)                                      \
		DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE)                                          \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE,       \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, va_list ap);         \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,  \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, va_list ap);         \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ...);

#define DEFINE_FAKE_VALUE_FUNC10_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,    \
					ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,     \
					ARG8_TYPE, ...)                                            \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ...)               \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				va_list ap;                                                        \
				va_start(ap, arg8);                                                \
				RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq                  \
							  [FUNCNAME##_fake.custom_fake_seq_idx++]( \
								  arg0, arg1, arg2, arg3, arg4,    \
								  arg5, arg6, arg7, arg8, ap);     \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				va_end(ap);                                                        \
				return ret;                                                        \
			} else {                                                                   \
				va_list ap;                                                        \
				va_start(ap, arg8);                                                \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_len - 1](         \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							arg7, arg8, ap);                           \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				va_end(ap);                                                        \
				return ret;                                                        \
				return FUNCNAME##_fake                                             \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, ap);                                         \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake) {                                                 \
			RETURN_TYPE ret;                                                           \
			va_list ap;                                                                \
			va_start(ap, arg8);                                                        \
			ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5,      \
							  arg6, arg7, arg8, ap);                   \
			va_end(ap);                                                                \
			SAVE_RET_HISTORY(FUNCNAME, ret);                                           \
			return ret;                                                                \
		}                                                                                  \
		RETURN_FAKE_RESULT(FUNCNAME)                                                       \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VALUE_FUNC10_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, \
				 ...)                                                              \
	DECLARE_FAKE_VALUE_FUNC10_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,    \
					 ARG8_TYPE, ...)                                           \
	DEFINE_FAKE_VALUE_FUNC10_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,    \
					ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,     \
					ARG8_TYPE, ...)

#define DECLARE_FAKE_VALUE_FUNC11_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,    \
					 ARG8_TYPE, ARG9_TYPE, ...)                                \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME)                                                \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE)                                      \
		DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE)                                          \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE,       \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     va_list ap);                                          \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,  \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     va_list ap);                                          \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		...);

#define DEFINE_FAKE_VALUE_FUNC11_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,    \
					ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,     \
					ARG8_TYPE, ARG9_TYPE, ...)                                 \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		...)                                                                               \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		SAVE_ARG(FUNCNAME, 9);                                                             \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 9);                                             \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				va_list ap;                                                        \
				va_start(ap, arg9);                                                \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_idx++](           \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							arg7, arg8, arg9, ap);                     \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				va_end(ap);                                                        \
				return ret;                                                        \
			} else {                                                                   \
				va_list ap;                                                        \
				va_start(ap, arg9);                                                \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_len - 1](         \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							arg7, arg8, arg9, ap);                     \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				va_end(ap);                                                        \
				return ret;                                                        \
				return FUNCNAME##_fake                                             \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, ap);                                   \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake) {                                                 \
			RETURN_TYPE ret;                                                           \
			va_list ap;                                                                \
			va_start(ap, arg9);                                                        \
			ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5,      \
							  arg6, arg7, arg8, arg9, ap);             \
			va_end(ap);                                                                \
			SAVE_RET_HISTORY(FUNCNAME, ret);                                           \
			return ret;                                                                \
		}                                                                                  \
		RETURN_FAKE_RESULT(FUNCNAME)                                                       \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VALUE_FUNC11_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, \
				 ARG9_TYPE, ...)                                                   \
	DECLARE_FAKE_VALUE_FUNC11_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,    \
					 ARG8_TYPE, ARG9_TYPE, ...)                                \
	DEFINE_FAKE_VALUE_FUNC11_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,    \
					ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,     \
					ARG8_TYPE, ARG9_TYPE, ...)

#define DECLARE_FAKE_VALUE_FUNC12_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,    \
					 ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...)                    \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME)                                                \
		DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME)                                              \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE)                                      \
		DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE)                                          \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE,       \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, va_list ap);                              \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,  \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, va_list ap);                              \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ...);

#define DEFINE_FAKE_VALUE_FUNC12_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,    \
					ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,     \
					ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...)                     \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ...)                                                             \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		SAVE_ARG(FUNCNAME, 9);                                                             \
		SAVE_ARG(FUNCNAME, 10);                                                            \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 9);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 10);                                            \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				va_list ap;                                                        \
				va_start(ap, arg10);                                               \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_idx++](           \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							arg7, arg8, arg9, arg10, ap);              \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				va_end(ap);                                                        \
				return ret;                                                        \
			} else {                                                                   \
				va_list ap;                                                        \
				va_start(ap, arg10);                                               \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_len - 1](         \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							arg7, arg8, arg9, arg10, ap);              \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				va_end(ap);                                                        \
				return ret;                                                        \
				return FUNCNAME##_fake                                             \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, ap);                            \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake) {                                                 \
			RETURN_TYPE ret;                                                           \
			va_list ap;                                                                \
			va_start(ap, arg10);                                                       \
			ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5,      \
							  arg6, arg7, arg8, arg9, arg10, ap);      \
			va_end(ap);                                                                \
			SAVE_RET_HISTORY(FUNCNAME, ret);                                           \
			return ret;                                                                \
		}                                                                                  \
		RETURN_FAKE_RESULT(FUNCNAME)                                                       \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VALUE_FUNC12_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, \
				 ARG9_TYPE, ARG10_TYPE, ...)                                       \
	DECLARE_FAKE_VALUE_FUNC12_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,    \
					 ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...)                    \
	DEFINE_FAKE_VALUE_FUNC12_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,    \
					ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,     \
					ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...)

#define DECLARE_FAKE_VALUE_FUNC13_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,    \
					 ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...)        \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME)                                                \
		DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME)                                              \
		DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME)                                              \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE)                                      \
		DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE)                                          \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE,       \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, va_list ap);                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,  \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, va_list ap);                  \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ...);

#define DEFINE_FAKE_VALUE_FUNC13_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,    \
					ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,     \
					ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...)         \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ...)                                           \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		SAVE_ARG(FUNCNAME, 9);                                                             \
		SAVE_ARG(FUNCNAME, 10);                                                            \
		SAVE_ARG(FUNCNAME, 11);                                                            \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 9);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 10);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 11);                                            \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				va_list ap;                                                        \
				va_start(ap, arg11);                                               \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_idx++](           \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							arg7, arg8, arg9, arg10, arg11, ap);       \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				va_end(ap);                                                        \
				return ret;                                                        \
			} else {                                                                   \
				va_list ap;                                                        \
				va_start(ap, arg11);                                               \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_len - 1](         \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							arg7, arg8, arg9, arg10, arg11, ap);       \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				va_end(ap);                                                        \
				return ret;                                                        \
				return FUNCNAME##_fake                                             \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, ap);                     \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake) {                                                 \
			RETURN_TYPE ret;                                                           \
			va_list ap;                                                                \
			va_start(ap, arg11);                                                       \
			ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5,      \
							  arg6, arg7, arg8, arg9, arg10, arg11,    \
							  ap);                                     \
			va_end(ap);                                                                \
			SAVE_RET_HISTORY(FUNCNAME, ret);                                           \
			return ret;                                                                \
		}                                                                                  \
		RETURN_FAKE_RESULT(FUNCNAME)                                                       \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VALUE_FUNC13_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, \
				 ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...)                           \
	DECLARE_FAKE_VALUE_FUNC13_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,    \
					 ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...)        \
	DEFINE_FAKE_VALUE_FUNC13_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,    \
					ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,     \
					ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...)

#define DECLARE_FAKE_VALUE_FUNC14_VARARG(                                                          \
	RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,   \
	ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...)       \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME)                                                \
		DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME)                                              \
		DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME)                                              \
		DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME)                                              \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE)                                      \
		DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE)                                          \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE,       \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, va_list ap);      \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,  \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, va_list ap);      \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ...);

#define DEFINE_FAKE_VALUE_FUNC14_VARARG(                                                           \
	RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,   \
	ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...)       \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ...)                         \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		SAVE_ARG(FUNCNAME, 9);                                                             \
		SAVE_ARG(FUNCNAME, 10);                                                            \
		SAVE_ARG(FUNCNAME, 11);                                                            \
		SAVE_ARG(FUNCNAME, 12);                                                            \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 9);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 10);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 11);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 12);                                            \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				va_list ap;                                                        \
				va_start(ap, arg12);                                               \
				RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq                  \
							  [FUNCNAME##_fake.custom_fake_seq_idx++]( \
								  arg0, arg1, arg2, arg3, arg4,    \
								  arg5, arg6, arg7, arg8, arg9,    \
								  arg10, arg11, arg12, ap);        \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				va_end(ap);                                                        \
				return ret;                                                        \
			} else {                                                                   \
				va_list ap;                                                        \
				va_start(ap, arg12);                                               \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_len - 1](         \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							arg7, arg8, arg9, arg10, arg11, arg12,     \
							ap);                                       \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				va_end(ap);                                                        \
				return ret;                                                        \
				return FUNCNAME##_fake                                             \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12, ap);              \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake) {                                                 \
			RETURN_TYPE ret;                                                           \
			va_list ap;                                                                \
			va_start(ap, arg12);                                                       \
			ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5,      \
							  arg6, arg7, arg8, arg9, arg10, arg11,    \
							  arg12, ap);                              \
			va_end(ap);                                                                \
			SAVE_RET_HISTORY(FUNCNAME, ret);                                           \
			return ret;                                                                \
		}                                                                                  \
		RETURN_FAKE_RESULT(FUNCNAME)                                                       \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VALUE_FUNC14_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, \
				 ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...)               \
	DECLARE_FAKE_VALUE_FUNC14_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,    \
					 ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, \
					 ...)                                                      \
	DEFINE_FAKE_VALUE_FUNC14_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,    \
					ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,     \
					ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE,  \
					...)

#define DECLARE_FAKE_VALUE_FUNC15_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,    \
					 ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, \
					 ARG13_TYPE, ...)                                          \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME)                                                \
		DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME)                                              \
		DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME)                                              \
		DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME)                                              \
		DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME)                                              \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE)                                      \
		DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE)                                          \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE,       \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,       \
					     va_list ap);                                          \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,  \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,       \
					     va_list ap);                                          \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ...);

#define DEFINE_FAKE_VALUE_FUNC15_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,    \
					ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,     \
					ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE,  \
					ARG13_TYPE, ...)                                           \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ...)       \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		SAVE_ARG(FUNCNAME, 9);                                                             \
		SAVE_ARG(FUNCNAME, 10);                                                            \
		SAVE_ARG(FUNCNAME, 11);                                                            \
		SAVE_ARG(FUNCNAME, 12);                                                            \
		SAVE_ARG(FUNCNAME, 13);                                                            \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 9);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 10);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 11);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 12);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 13);                                            \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				va_list ap;                                                        \
				va_start(ap, arg13);                                               \
				RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq                  \
							  [FUNCNAME##_fake.custom_fake_seq_idx++]( \
								  arg0, arg1, arg2, arg3, arg4,    \
								  arg5, arg6, arg7, arg8, arg9,    \
								  arg10, arg11, arg12, arg13, ap); \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				va_end(ap);                                                        \
				return ret;                                                        \
			} else {                                                                   \
				va_list ap;                                                        \
				va_start(ap, arg13);                                               \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_len - 1](         \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							arg7, arg8, arg9, arg10, arg11, arg12,     \
							arg13, ap);                                \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				va_end(ap);                                                        \
				return ret;                                                        \
				return FUNCNAME##_fake                                             \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12, arg13, ap);       \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake) {                                                 \
			RETURN_TYPE ret;                                                           \
			va_list ap;                                                                \
			va_start(ap, arg13);                                                       \
			ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5,      \
							  arg6, arg7, arg8, arg9, arg10, arg11,    \
							  arg12, arg13, ap);                       \
			va_end(ap);                                                                \
			SAVE_RET_HISTORY(FUNCNAME, ret);                                           \
			return ret;                                                                \
		}                                                                                  \
		RETURN_FAKE_RESULT(FUNCNAME)                                                       \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VALUE_FUNC15_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, \
				 ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...)   \
	DECLARE_FAKE_VALUE_FUNC15_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,    \
					 ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, \
					 ARG13_TYPE, ...)                                          \
	DEFINE_FAKE_VALUE_FUNC15_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,    \
					ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,     \
					ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE,  \
					ARG13_TYPE, ...)

#define DECLARE_FAKE_VALUE_FUNC16_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,    \
					 ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, \
					 ARG13_TYPE, ARG14_TYPE, ...)                              \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME)                                                \
		DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME)                                              \
		DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME)                                              \
		DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME)                                              \
		DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME)                                              \
		DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME)                                              \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE)                                      \
		DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE)                                          \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE,       \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,       \
					     ARG14_TYPE, va_list ap);                              \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,  \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,       \
					     ARG14_TYPE, va_list ap);                              \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14, ...);

#define DEFINE_FAKE_VALUE_FUNC16_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,    \
					ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,     \
					ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE,  \
					ARG13_TYPE, ARG14_TYPE, ...)                               \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14, ...)                                                             \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		SAVE_ARG(FUNCNAME, 9);                                                             \
		SAVE_ARG(FUNCNAME, 10);                                                            \
		SAVE_ARG(FUNCNAME, 11);                                                            \
		SAVE_ARG(FUNCNAME, 12);                                                            \
		SAVE_ARG(FUNCNAME, 13);                                                            \
		SAVE_ARG(FUNCNAME, 14);                                                            \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 9);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 10);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 11);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 12);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 13);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 14);                                            \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				va_list ap;                                                        \
				va_start(ap, arg14);                                               \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_idx++](           \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							arg7, arg8, arg9, arg10, arg11, arg12,     \
							arg13, arg14, ap);                         \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				va_end(ap);                                                        \
				return ret;                                                        \
			} else {                                                                   \
				va_list ap;                                                        \
				va_start(ap, arg14);                                               \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_len - 1](         \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							arg7, arg8, arg9, arg10, arg11, arg12,     \
							arg13, arg14, ap);                         \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				va_end(ap);                                                        \
				return ret;                                                        \
				return FUNCNAME##_fake                                             \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12, arg13, arg14,     \
						ap);                                               \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake) {                                                 \
			RETURN_TYPE ret;                                                           \
			va_list ap;                                                                \
			va_start(ap, arg14);                                                       \
			ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5,      \
							  arg6, arg7, arg8, arg9, arg10, arg11,    \
							  arg12, arg13, arg14, ap);                \
			va_end(ap);                                                                \
			SAVE_RET_HISTORY(FUNCNAME, ret);                                           \
			return ret;                                                                \
		}                                                                                  \
		RETURN_FAKE_RESULT(FUNCNAME)                                                       \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VALUE_FUNC16_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, \
				 ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,        \
				 ARG14_TYPE, ...)                                                  \
	DECLARE_FAKE_VALUE_FUNC16_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,    \
					 ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, \
					 ARG13_TYPE, ARG14_TYPE, ...)                              \
	DEFINE_FAKE_VALUE_FUNC16_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,    \
					ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,     \
					ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE,  \
					ARG13_TYPE, ARG14_TYPE, ...)

#define DECLARE_FAKE_VALUE_FUNC17_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,    \
					 ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, \
					 ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...)                  \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME)                                                \
		DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME)                                              \
		DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME)                                              \
		DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME)                                              \
		DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME)                                              \
		DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME)                                              \
		DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME)                                              \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE)                                      \
		DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE)                                          \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE,       \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,       \
					     ARG14_TYPE, ARG15_TYPE, va_list ap);                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,  \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,       \
					     ARG14_TYPE, ARG15_TYPE, va_list ap);                  \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14, ARG15_TYPE arg15, ...);

#define DEFINE_FAKE_VALUE_FUNC17_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,    \
					ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,     \
					ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE,  \
					ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...)                   \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14, ARG15_TYPE arg15, ...)                                           \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		SAVE_ARG(FUNCNAME, 9);                                                             \
		SAVE_ARG(FUNCNAME, 10);                                                            \
		SAVE_ARG(FUNCNAME, 11);                                                            \
		SAVE_ARG(FUNCNAME, 12);                                                            \
		SAVE_ARG(FUNCNAME, 13);                                                            \
		SAVE_ARG(FUNCNAME, 14);                                                            \
		SAVE_ARG(FUNCNAME, 15);                                                            \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 9);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 10);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 11);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 12);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 13);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 14);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 15);                                            \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				va_list ap;                                                        \
				va_start(ap, arg15);                                               \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_idx++](           \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							arg7, arg8, arg9, arg10, arg11, arg12,     \
							arg13, arg14, arg15, ap);                  \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				va_end(ap);                                                        \
				return ret;                                                        \
			} else {                                                                   \
				va_list ap;                                                        \
				va_start(ap, arg15);                                               \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_len - 1](         \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							arg7, arg8, arg9, arg10, arg11, arg12,     \
							arg13, arg14, arg15, ap);                  \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				va_end(ap);                                                        \
				return ret;                                                        \
				return FUNCNAME##_fake                                             \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12, arg13, arg14,     \
						arg15, ap);                                        \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake) {                                                 \
			RETURN_TYPE ret;                                                           \
			va_list ap;                                                                \
			va_start(ap, arg15);                                                       \
			ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5,      \
							  arg6, arg7, arg8, arg9, arg10, arg11,    \
							  arg12, arg13, arg14, arg15, ap);         \
			va_end(ap);                                                                \
			SAVE_RET_HISTORY(FUNCNAME, ret);                                           \
			return ret;                                                                \
		}                                                                                  \
		RETURN_FAKE_RESULT(FUNCNAME)                                                       \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VALUE_FUNC17_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, \
				 ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,        \
				 ARG14_TYPE, ARG15_TYPE, ...)                                      \
	DECLARE_FAKE_VALUE_FUNC17_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,    \
					 ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, \
					 ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...)                  \
	DEFINE_FAKE_VALUE_FUNC17_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,    \
					ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,     \
					ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE,  \
					ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...)

#define DECLARE_FAKE_VALUE_FUNC18_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,    \
					 ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, \
					 ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...)      \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME)                                                \
		DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME)                                              \
		DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME)                                              \
		DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME)                                              \
		DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME)                                              \
		DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME)                                              \
		DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME)                                              \
		DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME)                                              \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE)                                      \
		DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE)                                          \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE,       \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,       \
					     ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, va_list ap);      \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,  \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,       \
					     ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, va_list ap);      \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ...);

#define DEFINE_FAKE_VALUE_FUNC18_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,    \
					ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,     \
					ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE,  \
					ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...)       \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ...)                         \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		SAVE_ARG(FUNCNAME, 9);                                                             \
		SAVE_ARG(FUNCNAME, 10);                                                            \
		SAVE_ARG(FUNCNAME, 11);                                                            \
		SAVE_ARG(FUNCNAME, 12);                                                            \
		SAVE_ARG(FUNCNAME, 13);                                                            \
		SAVE_ARG(FUNCNAME, 14);                                                            \
		SAVE_ARG(FUNCNAME, 15);                                                            \
		SAVE_ARG(FUNCNAME, 16);                                                            \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 9);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 10);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 11);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 12);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 13);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 14);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 15);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 16);                                            \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				va_list ap;                                                        \
				va_start(ap, arg16);                                               \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_idx++](           \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							arg7, arg8, arg9, arg10, arg11, arg12,     \
							arg13, arg14, arg15, arg16, ap);           \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				va_end(ap);                                                        \
				return ret;                                                        \
			} else {                                                                   \
				va_list ap;                                                        \
				va_start(ap, arg16);                                               \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_len - 1](         \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							arg7, arg8, arg9, arg10, arg11, arg12,     \
							arg13, arg14, arg15, arg16, ap);           \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				va_end(ap);                                                        \
				return ret;                                                        \
				return FUNCNAME##_fake                                             \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12, arg13, arg14,     \
						arg15, arg16, ap);                                 \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake) {                                                 \
			RETURN_TYPE ret;                                                           \
			va_list ap;                                                                \
			va_start(ap, arg16);                                                       \
			ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5,      \
							  arg6, arg7, arg8, arg9, arg10, arg11,    \
							  arg12, arg13, arg14, arg15, arg16, ap);  \
			va_end(ap);                                                                \
			SAVE_RET_HISTORY(FUNCNAME, ret);                                           \
			return ret;                                                                \
		}                                                                                  \
		RETURN_FAKE_RESULT(FUNCNAME)                                                       \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VALUE_FUNC18_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, \
				 ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,        \
				 ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...)                          \
	DECLARE_FAKE_VALUE_FUNC18_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,    \
					 ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, \
					 ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...)      \
	DEFINE_FAKE_VALUE_FUNC18_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,    \
					ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,     \
					ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE,  \
					ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...)

#define DECLARE_FAKE_VALUE_FUNC19_VARARG(                                                          \
	RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,   \
	ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE,            \
	ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...)                           \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME)                                                \
		DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME)                                              \
		DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME)                                              \
		DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME)                                              \
		DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME)                                              \
		DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME)                                              \
		DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME)                                              \
		DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME)                                              \
		DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME)                                              \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE)                                      \
		DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE)                                          \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE,       \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,       \
					     ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE,       \
					     va_list ap);                                          \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,  \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,       \
					     ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE,       \
					     va_list ap);                                          \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ...);

#define DEFINE_FAKE_VALUE_FUNC19_VARARG(                                                           \
	RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,   \
	ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE,            \
	ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...)                           \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ...)       \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		SAVE_ARG(FUNCNAME, 9);                                                             \
		SAVE_ARG(FUNCNAME, 10);                                                            \
		SAVE_ARG(FUNCNAME, 11);                                                            \
		SAVE_ARG(FUNCNAME, 12);                                                            \
		SAVE_ARG(FUNCNAME, 13);                                                            \
		SAVE_ARG(FUNCNAME, 14);                                                            \
		SAVE_ARG(FUNCNAME, 15);                                                            \
		SAVE_ARG(FUNCNAME, 16);                                                            \
		SAVE_ARG(FUNCNAME, 17);                                                            \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 9);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 10);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 11);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 12);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 13);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 14);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 15);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 16);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 17);                                            \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				va_list ap;                                                        \
				va_start(ap, arg17);                                               \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_idx++](           \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							arg7, arg8, arg9, arg10, arg11, arg12,     \
							arg13, arg14, arg15, arg16, arg17, ap);    \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				va_end(ap);                                                        \
				return ret;                                                        \
			} else {                                                                   \
				va_list ap;                                                        \
				va_start(ap, arg17);                                               \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_len - 1](         \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							arg7, arg8, arg9, arg10, arg11, arg12,     \
							arg13, arg14, arg15, arg16, arg17, ap);    \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				va_end(ap);                                                        \
				return ret;                                                        \
				return FUNCNAME##_fake                                             \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12, arg13, arg14,     \
						arg15, arg16, arg17, ap);                          \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake) {                                                 \
			RETURN_TYPE ret;                                                           \
			va_list ap;                                                                \
			va_start(ap, arg17);                                                       \
			ret = FUNCNAME##_fake.custom_fake(                                         \
				arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, \
				arg11, arg12, arg13, arg14, arg15, arg16, arg17, ap);              \
			va_end(ap);                                                                \
			SAVE_RET_HISTORY(FUNCNAME, ret);                                           \
			return ret;                                                                \
		}                                                                                  \
		RETURN_FAKE_RESULT(FUNCNAME)                                                       \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VALUE_FUNC19_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, \
				 ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,        \
				 ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...)              \
	DECLARE_FAKE_VALUE_FUNC19_VARARG(                                                          \
		RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,      \
		ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE,     \
		ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...)       \
	DEFINE_FAKE_VALUE_FUNC19_VARARG(                                                           \
		RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE,      \
		ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE,     \
		ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...)

#define DECLARE_FAKE_VALUE_FUNC20_VARARG(                                                          \
	RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,   \
	ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE,            \
	ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...)               \
	typedef struct FUNCNAME##_Fake {                                                           \
		DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME)                                                \
		DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME)                                                \
		DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME)                                                \
		DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME)                                                \
		DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME)                                                \
		DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME)                                                \
		DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME)                                                \
		DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME)                                                \
		DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME)                                                \
		DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME)                                                \
		DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME)                                              \
		DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME)                                              \
		DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME)                                              \
		DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME)                                              \
		DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME)                                              \
		DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME)                                              \
		DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME)                                              \
		DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME)                                              \
		DECLARE_ARG(ARG18_TYPE, 18, FUNCNAME)                                              \
		DECLARE_ALL_FUNC_COMMON                                                            \
		DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE)                                      \
		DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE)                                          \
		DECLARE_CUSTOM_FAKE_SEQ_VARIABLES                                                  \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE,       \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,       \
					     ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE,       \
					     ARG18_TYPE, va_list ap);                              \
		CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE,  \
					     ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,           \
					     ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE,           \
					     ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,       \
					     ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE,       \
					     ARG18_TYPE, va_list ap);                              \
	} FUNCNAME##_Fake;                                                                         \
	extern FUNCNAME##_Fake FUNCNAME##_fake;                                                    \
	void FUNCNAME##_reset(void);                                                               \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17,            \
		ARG18_TYPE arg18, ...);

#define DEFINE_FAKE_VALUE_FUNC20_VARARG(                                                           \
	RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE,   \
	ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE,            \
	ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...)               \
	FUNCNAME##_Fake FUNCNAME##_fake;                                                           \
	RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(                                          \
		ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4,    \
		ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9,    \
		ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13,            \
		ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17,            \
		ARG18_TYPE arg18, ...)                                                             \
	{                                                                                          \
		SAVE_ARG(FUNCNAME, 0);                                                             \
		SAVE_ARG(FUNCNAME, 1);                                                             \
		SAVE_ARG(FUNCNAME, 2);                                                             \
		SAVE_ARG(FUNCNAME, 3);                                                             \
		SAVE_ARG(FUNCNAME, 4);                                                             \
		SAVE_ARG(FUNCNAME, 5);                                                             \
		SAVE_ARG(FUNCNAME, 6);                                                             \
		SAVE_ARG(FUNCNAME, 7);                                                             \
		SAVE_ARG(FUNCNAME, 8);                                                             \
		SAVE_ARG(FUNCNAME, 9);                                                             \
		SAVE_ARG(FUNCNAME, 10);                                                            \
		SAVE_ARG(FUNCNAME, 11);                                                            \
		SAVE_ARG(FUNCNAME, 12);                                                            \
		SAVE_ARG(FUNCNAME, 13);                                                            \
		SAVE_ARG(FUNCNAME, 14);                                                            \
		SAVE_ARG(FUNCNAME, 15);                                                            \
		SAVE_ARG(FUNCNAME, 16);                                                            \
		SAVE_ARG(FUNCNAME, 17);                                                            \
		SAVE_ARG(FUNCNAME, 18);                                                            \
		if (ROOM_FOR_MORE_HISTORY(FUNCNAME)) {                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 0);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 1);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 2);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 3);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 4);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 5);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 6);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 7);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 8);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 9);                                             \
			SAVE_ARG_HISTORY(FUNCNAME, 10);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 11);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 12);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 13);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 14);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 15);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 16);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 17);                                            \
			SAVE_ARG_HISTORY(FUNCNAME, 18);                                            \
		} else {                                                                           \
			HISTORY_DROPPED(FUNCNAME);                                                 \
		}                                                                                  \
		INCREMENT_CALL_COUNT(FUNCNAME);                                                    \
		REGISTER_CALL(FUNCNAME);                                                           \
		if (FUNCNAME##_fake.custom_fake_seq_len) { /* a sequence of custom fakes */        \
			if (FUNCNAME##_fake.custom_fake_seq_idx <                                  \
			    FUNCNAME##_fake.custom_fake_seq_len) {                                 \
				va_list ap;                                                        \
				va_start(ap, arg18);                                               \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_idx++](           \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							arg7, arg8, arg9, arg10, arg11, arg12,     \
							arg13, arg14, arg15, arg16, arg17, arg18,  \
							ap);                                       \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				va_end(ap);                                                        \
				return ret;                                                        \
			} else {                                                                   \
				va_list ap;                                                        \
				va_start(ap, arg18);                                               \
				RETURN_TYPE ret =                                                  \
					FUNCNAME##_fake.custom_fake_seq                            \
						[FUNCNAME##_fake.custom_fake_seq_len - 1](         \
							arg0, arg1, arg2, arg3, arg4, arg5, arg6,  \
							arg7, arg8, arg9, arg10, arg11, arg12,     \
							arg13, arg14, arg15, arg16, arg17, arg18,  \
							ap);                                       \
				SAVE_RET_HISTORY(FUNCNAME, ret);                                   \
				va_end(ap);                                                        \
				return ret;                                                        \
				return FUNCNAME##_fake                                             \
					.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len - 1]( \
						arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7,    \
						arg8, arg9, arg10, arg11, arg12, arg13, arg14,     \
						arg15, arg16, arg17, arg18, ap);                   \
			}                                                                          \
		}                                                                                  \
		if (FUNCNAME##_fake.custom_fake) {                                                 \
			RETURN_TYPE ret;                                                           \
			va_list ap;                                                                \
			va_start(ap, arg18);                                                       \
			ret = FUNCNAME##_fake.custom_fake(                                         \
				arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, \
				arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, ap);       \
			va_end(ap);                                                                \
			SAVE_RET_HISTORY(FUNCNAME, ret);                                           \
			return ret;                                                                \
		}                                                                                  \
		RETURN_FAKE_RESULT(FUNCNAME)                                                       \
	}                                                                                          \
	DEFINE_RESET_FUNCTION(FUNCNAME)

#define FAKE_VALUE_FUNC20_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,           \
				 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, \
				 ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE,        \
				 ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...)  \
	DECLARE_FAKE_VALUE_FUNC20_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,   \
					 ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,    \
					 ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, \
					 ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE,           \
					 ARG17_TYPE, ARG18_TYPE, ...)                              \
	DEFINE_FAKE_VALUE_FUNC20_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE,    \
					ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE,     \
					ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE,  \
					ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE,            \
					ARG17_TYPE, ARG18_TYPE, ...)

/* MSVC expand macro fix */
#define EXPAND(x) x

#define PP_NARG_MINUS2(...) EXPAND(PP_NARG_MINUS2_(__VA_ARGS__, PP_RSEQ_N_MINUS2()))

#define PP_NARG_MINUS2_(...) EXPAND(PP_ARG_MINUS2_N(__VA_ARGS__))

#define PP_ARG_MINUS2_N(returnVal, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13,     \
			_14, _15, _16, _17, _18, _19, _20, N, ...)                                 \
	N

#define PP_RSEQ_N_MINUS2() 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0

#define PP_NARG_MINUS1(...) EXPAND(PP_NARG_MINUS1_(__VA_ARGS__, PP_RSEQ_N_MINUS1()))

#define PP_NARG_MINUS1_(...) EXPAND(PP_ARG_MINUS1_N(__VA_ARGS__))

#define PP_ARG_MINUS1_N(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, \
			_17, _18, _19, _20, N, ...)                                                \
	N

#define PP_RSEQ_N_MINUS1() 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0

/* DECLARE AND DEFINE FAKE FUNCTIONS - PLACE IN TEST FILES */

#define FAKE_VALUE_FUNC(...) EXPAND(FUNC_VALUE_(PP_NARG_MINUS2(__VA_ARGS__), __VA_ARGS__))

#define FUNC_VALUE_(N, ...) EXPAND(FUNC_VALUE_N(N, __VA_ARGS__))

#define FUNC_VALUE_N(N, ...) EXPAND(FAKE_VALUE_FUNC##N(__VA_ARGS__))

#define FAKE_VOID_FUNC(...) EXPAND(FUNC_VOID_(PP_NARG_MINUS1(__VA_ARGS__), __VA_ARGS__))

#define FUNC_VOID_(N, ...) EXPAND(FUNC_VOID_N(N, __VA_ARGS__))

#define FUNC_VOID_N(N, ...) EXPAND(FAKE_VOID_FUNC##N(__VA_ARGS__))

#define FAKE_VALUE_FUNC_VARARG(...)                                                                \
	EXPAND(FUNC_VALUE_VARARG_(PP_NARG_MINUS2(__VA_ARGS__), __VA_ARGS__))

#define FUNC_VALUE_VARARG_(N, ...) EXPAND(FUNC_VALUE_VARARG_N(N, __VA_ARGS__))

#define FUNC_VALUE_VARARG_N(N, ...) EXPAND(FAKE_VALUE_FUNC##N##_VARARG(__VA_ARGS__))

#define FAKE_VOID_FUNC_VARARG(...)                                                                 \
	EXPAND(FUNC_VOID_VARARG_(PP_NARG_MINUS1(__VA_ARGS__), __VA_ARGS__))

#define FUNC_VOID_VARARG_(N, ...) EXPAND(FUNC_VOID_VARARG_N(N, __VA_ARGS__))

#define FUNC_VOID_VARARG_N(N, ...) EXPAND(FAKE_VOID_FUNC##N##_VARARG(__VA_ARGS__))

/* DECLARE FAKE FUNCTIONS - PLACE IN HEADER FILES */

#define DECLARE_FAKE_VALUE_FUNC(...)                                                               \
	EXPAND(DECLARE_FUNC_VALUE_(PP_NARG_MINUS2(__VA_ARGS__), __VA_ARGS__))

#define DECLARE_FUNC_VALUE_(N, ...) EXPAND(DECLARE_FUNC_VALUE_N(N, __VA_ARGS__))

#define DECLARE_FUNC_VALUE_N(N, ...) EXPAND(DECLARE_FAKE_VALUE_FUNC##N(__VA_ARGS__))

#define DECLARE_FAKE_VOID_FUNC(...)                                                                \
	EXPAND(DECLARE_FUNC_VOID_(PP_NARG_MINUS1(__VA_ARGS__), __VA_ARGS__))

#define DECLARE_FUNC_VOID_(N, ...) EXPAND(DECLARE_FUNC_VOID_N(N, __VA_ARGS__))

#define DECLARE_FUNC_VOID_N(N, ...) EXPAND(DECLARE_FAKE_VOID_FUNC##N(__VA_ARGS__))

#define DECLARE_FAKE_VALUE_FUNC_VARARG(...)                                                        \
	EXPAND(DECLARE_FUNC_VALUE_VARARG_(PP_NARG_MINUS2(__VA_ARGS__), __VA_ARGS__))

#define DECLARE_FUNC_VALUE_VARARG_(N, ...) EXPAND(DECLARE_FUNC_VALUE_VARARG_N(N, __VA_ARGS__))

#define DECLARE_FUNC_VALUE_VARARG_N(N, ...) EXPAND(DECLARE_FAKE_VALUE_FUNC##N##_VARARG(__VA_ARGS__))

#define DECLARE_FAKE_VOID_FUNC_VARARG(...)                                                         \
	EXPAND(DECLARE_FUNC_VOID_VARARG_(PP_NARG_MINUS1(__VA_ARGS__), __VA_ARGS__))

#define DECLARE_FUNC_VOID_VARARG_(N, ...) EXPAND(DECLARE_FUNC_VOID_VARARG_N(N, __VA_ARGS__))

#define DECLARE_FUNC_VOID_VARARG_N(N, ...) EXPAND(DECLARE_FAKE_VOID_FUNC##N##_VARARG(__VA_ARGS__))

/* DEFINE FAKE FUNCTIONS - PLACE IN SOURCE FILES */

#define DEFINE_FAKE_VALUE_FUNC(...)                                                                \
	EXPAND(DEFINE_FUNC_VALUE_(PP_NARG_MINUS2(__VA_ARGS__), __VA_ARGS__))

#define DEFINE_FUNC_VALUE_(N, ...) EXPAND(DEFINE_FUNC_VALUE_N(N, __VA_ARGS__))

#define DEFINE_FUNC_VALUE_N(N, ...) EXPAND(DEFINE_FAKE_VALUE_FUNC##N(__VA_ARGS__))

#define DEFINE_FAKE_VOID_FUNC(...)                                                                 \
	EXPAND(DEFINE_FUNC_VOID_(PP_NARG_MINUS1(__VA_ARGS__), __VA_ARGS__))

#define DEFINE_FUNC_VOID_(N, ...) EXPAND(DEFINE_FUNC_VOID_N(N, __VA_ARGS__))

#define DEFINE_FUNC_VOID_N(N, ...) EXPAND(DEFINE_FAKE_VOID_FUNC##N(__VA_ARGS__))

#define DEFINE_FAKE_VALUE_FUNC_VARARG(...)                                                         \
	EXPAND(DEFINE_FUNC_VALUE_VARARG_(PP_NARG_MINUS2(__VA_ARGS__), __VA_ARGS__))

#define DEFINE_FUNC_VALUE_VARARG_(N, ...) EXPAND(DEFINE_FUNC_VALUE_VARARG_N(N, __VA_ARGS__))

#define DEFINE_FUNC_VALUE_VARARG_N(N, ...) EXPAND(DEFINE_FAKE_VALUE_FUNC##N##_VARARG(__VA_ARGS__))

#define DEFINE_FAKE_VOID_FUNC_VARARG(...)                                                          \
	EXPAND(DEFINE_FUNC_VOID_VARARG_(PP_NARG_MINUS1(__VA_ARGS__), __VA_ARGS__))

#define DEFINE_FUNC_VOID_VARARG_(N, ...) EXPAND(DEFINE_FUNC_VOID_VARARG_N(N, __VA_ARGS__))

#define DEFINE_FUNC_VOID_VARARG_N(N, ...) EXPAND(DEFINE_FAKE_VOID_FUNC##N##_VARARG(__VA_ARGS__))

#endif /* FAKE_FUNCTIONS */
